I'm new to using wait() and notify() in Java and I'm getting an IllegalMonitorStateException.
Main Code
public class ThreadTest {
private static Integer state = 0;
public static void main(String[] args) {
synchronized(state) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
synchronized(state) {
state = 0;
while(state == 0) {
try {
state.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
}
public static class AnotherTest implements Runnable {
#Override
public void run() {
synchronized(state) {
state = 1;
state.notify();
}
}
}
}
I'm getting an IllegalMonitorStateException what state.notify() is called. Any ideas?
Edit: Based on answer below here is code that works. As a side note, I was first trying this with an enum which has the same problem of using Integer.
public class ThreadTest {
private static int state = 0;
private static Object monitor = new Object();
public static void main(String[] args) {
synchronized(monitor) {
System.out.println("Starting thread");
Thread t = new Thread(new AnotherTest());
t.start();
state = 0;
while(state == 0) {
try {
for(int i = 0; i < 5; i++) {
System.out.println("Waiting " + (5 - i) + " Seconds");
Thread.sleep(1000);
}
monitor.wait(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("State is: " + state);
}
}
public static class AnotherTest implements Runnable {
#Override
public void run() {
synchronized(monitor) {
state = 1;
monitor.notify();
}
}
}
}
This
private static Integer state = 0;
is equivalent to
private static Integer state = Integer.valueOf(0);
The invocation of valueOf(0) returns a reference to an Integer object, call it A.
You then do
synchronized(state) {
your thread acquires the lock on the object referenced by state, currently that is A.
You then do
state = 1;
which is equivalent to
state = Integer.valueOf(1);
which gives you a different reference to an Integer object, call it B, and assigns it to state. When you then call
state.notify();
you're invoking notify() on an object, B, for which your thread doesn't own the monitor. You can't call notify or wait on objects for which your thread doesn't own the monitor.
Related
I was trying the wait and notify scenario, getting --> Exception in thread "Thread-1" java.lang.IllegalMonitorStateException when calling notify.
wait method releases the lock, so the threadB can execute the and from threadB i'm calling lock.notify for threadA.
Could you help me on this?
class SynchronizedCodee {
int a = 5;
Lock lock = new ReentrantLock();
public void threadA()
{
lock.lock();
try {
lock.wait();
System.out.println("A = "+a);
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
finally
{
lock.unlock();
}
}
public void threadB()
{
if(lock.tryLock())
{
this.a = 11;
System.out.println("B = "+a);
lock.notify(); // getting erro over here
}
else
{
System.out.println("didn't managed to get a lock");
}
}
}
class ThreadA extends Thread{
SynchronizedCodee s;
public ThreadA(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadA();
}
}
class ThreadB extends Thread{
SynchronizedCodee s;
public ThreadB(SynchronizedCodee s) {
this.s = s;
}
public void run()
{
s.threadB();
}
}
public class SynchronizedCode{
public static void main(String ag[]) throws InterruptedException
{
SynchronizedCodee s = new SynchronizedCodee();
ThreadA t1 = new ThreadA(s);
ThreadB t2 = new ThreadB(s);
t1.start();
Thread.sleep(100);
t2.start();
}
}
You are calling wait and notify on explicit lock objects and that is not legal. If you are using explicit lock objects, you have to use Condition object associated with it. Then you should call condition.await and condition.signalAll methods instead of wait and notify. Here's the idiom for using explicit locks in your particular scenario.
final Condition setA = lock.newCondition();
public void threadA() {
lock.lock();
try {
while (a == 5)
setA.await();
System.out.println("A = " + a);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
public void threadB() {
lock.lock();
try {
this.a = 11;
System.out.println("B = " + a);
setA.signalAll();
} finally {
lock.unlock();
}
}
And this program produces the following output:
B = 11
A = 11
Hi I am trying to print even and odd using two threads namedly EvenThread and OddThread, some times I am getting correct result and some times not, could any one please help me.
package com.java8;
public class EvenOddExample {
public static synchronized void print(int i,String name){
System.out.println(i+"--->"+name);
}
public static void main(String[] args) throws InterruptedException {
EvenThread e= new EvenThread();
e.start();
OddThread o=new OddThread();
o.start();
}
public static class EvenThread extends Thread{
public void run() {
for(int i=0;i<10;i++){
if(i%2==0){
print(i,"Even");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public static class OddThread extends Thread{
#Override
public void run() {
for(int i=1;i<10;i++){
if(i%2!=0){
print(i,"Odd");
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
You need some signaling between the two threads. Putting synchronized on the print method simply guarantees, that only one thread can enter the method at a time. To put your threads into order Object.wait() and Object.notify{All}() methods can be used.
Actually this is some kind of the Sender-Receiver Synchronization Problem. Based on the example of the problem described here (Please read this page in order to understand how this synchronization works) I adapted your code. Additionally I used ExecutorService and Callable instead of extending Thread, which is bad-practice:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class EvenOddExample {
private static boolean evensTurn = true;
private static Object monitor = new Object();
public static void print(int i, String name) {
System.out.println(i + "--->" + name);
}
public static void main(String[] args) throws InterruptedException {
final ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(new EvenCallable());
executorService.submit(new OddCallable());
executorService.shutdown();
}
public static class EvenCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
synchronized (monitor) {
while (!evensTurn) { // not your turn?
monitor.wait(); // wait for monitor in a loop to handle spurious wakeups
}
print(i, "Even");
evensTurn = false; // next odd needs to run
monitor.notifyAll(); // wakeup the odd thread
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
public static class OddCallable implements Callable<Void> {
#Override
public Void call() throws InterruptedException {
for (int i = 1; i < 10; i++) {
if (i % 2 != 0) {
synchronized (monitor) {
while (evensTurn) {
monitor.wait();
}
print(i, "Odd");
evensTurn = true;
monitor.notifyAll();
}
} else {
Thread.sleep(1000);
}
}
return null;
}
}
}
synchronized is used to lock the access of another thread, when the locked object is free, it does not guarantee which is next called thread. You can use semaphore to make inter-thread communication:
private static Semaphore[] semaphores = {new Semaphore(0), new Semaphore(1)};
static void print(int i, String name) {
try {
semaphores[(i + 1) % 2].acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(i + "--->" + name);
semaphores[i % 2].release();
}
public class EvenOddPrinter {
static boolean flag = true;
public static void main(String[] args) {
class Odd implements Runnable {
#Override
public void run() {
for (int i = 1; i <= 10;) {
if (EvenOddPrinter.flag) {
System.out.println(i + "--->odd");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
class Even implements Runnable {
#Override
public void run() {
for (int i = 2; i <= 10;) {
if (!EvenOddPrinter.flag) {
System.out.println(i + "---->even");
i += 2;
EvenOddPrinter.flag = !EvenOddPrinter.flag;
}
}
}
}
Runnable odd = new Even();
Runnable even = new Odd();
Thread t1 = new Thread(odd, "Odd");
Thread t2 = new Thread(even, "Even");
t1.start();
t2.start();
}
}
Today I was doing some practice on Thread and was trying to create one Even Odd number program. I created this using synchronized and it was working fine.
But when I tried to do the same thing using Lock then I stuck.
Below is the code that I am trying to do the same.
public class OddEvenNumberThreadLock {
public static void main(String args[]) {
SharedObject sharedObject = new SharedObject();
Thread evenThread = new Thread(new EvenNumber(sharedObject));
Thread oddThread = new Thread(new OddNumber(sharedObject));
evenThread.start();
oddThread.start();
}
}
class EvenNumber implements Runnable {
SharedObject object;
public EvenNumber(SharedObject object) {
this.object = object;
}
#Override
public void run() {
for (int i = 0; i <= 100; i = i + 2) {
while (!object.isOdd()) {
object.getLock().lock();
try {
System.out.println("Even : " + i);
object.setOdd(true);
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
}
class OddNumber implements Runnable {
SharedObject object;
public OddNumber(SharedObject object) {
this.object = object;
}
#Override
public void run() {
for (int i = 1; i <= 100; i = i + 2) {
while (object.isOdd()) {
object.getLock().lock();
try {
System.out.println("Odd : " + i);
object.setOdd(false);
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
}
class SharedObject {
private Lock lock;
private boolean isOdd;
public SharedObject() {
this.lock = new ReentrantLock();
}
public boolean isOdd() {
return isOdd;
}
public void setOdd(boolean isOdd) {
this.isOdd = isOdd;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
}
I have one more question there like in the case of synchronized we use notify method to inform other thread. How we can achieve this thing in case of Lock.
Thanks
As far as I can tell you want to achieve that the two threads of yours print even and odd numbers in a ping-pong style. The behavior you want is easier to achieve with ReentrantLock than with synchronized block since synchronized is always unfair, but you can make ReentrantLock to be fair using the aproppriate constructor. Here is how your program would look like with Locks:
public class App {
public static void main(String args[]) {
SharedObject sharedObject = new SharedObject();
Thread evenThread = new Thread(new EvenNumber(sharedObject));
Thread oddThread = new Thread(new OddNumber(sharedObject));
evenThread.start();
oddThread.start();
}
}
class EvenNumber implements Runnable {
SharedObject object;
public EvenNumber(SharedObject object) {
this.object = object;
}
public void run() {
int i = 0;
while(i <= 100) {
object.getLock().lock();
try {
if (!object.isOdd()) {
System.out.println("Even : " + i);
i = i + 2;
object.setOdd(true);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
class OddNumber implements Runnable {
SharedObject object;
public OddNumber(SharedObject object) {
this.object = object;
}
public void run() {
int i = 1;
while(i <= 100) {
object.getLock().lock();
try {
if(object.isOdd()) {
System.out.println("Odd : " + i);
i = i + 2;
object.setOdd(false);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
object.getLock().unlock();
}
}
}
}
class SharedObject {
private Lock lock;
private boolean isOdd;
public SharedObject() {
this.lock = new ReentrantLock(true);
}
public boolean isOdd() {
return isOdd;
}
public void setOdd(boolean isOdd) {
this.isOdd = isOdd;
}
public Lock getLock() {
return lock;
}
public void setLock(Lock lock) {
this.lock = lock;
}
}
I wrote a simple program to learn about synchronized block. The program is as follow:
public class SychronizedBlock {
static int balance = 0;
static Integer lock = 0;
public static void deposit(int amt) {
Thread t1 = new Thread(new Runnable() {
public void run() {
acquire_lock();
int holdings = balance;
balance = holdings + amt;
System.out.println("deposit " + amt + ", balance: " + balance);
release_lock();
}
});
t1.start();
}
public static void acquire_lock() {
synchronized(lock) {
while (lock == 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lock = 1;
}
}
public static void release_lock() {
synchronized(lock) {
lock = 0;
lock.notifyAll();
}
}
public static void test1() {
balance = 0;
deposit(500);
deposit(500);
}
public static void main(String[] args) {
test1();
}
}
However, when running the program, I met with an IllegalMonitorStateException. I think I have place the wait() and notifyAll() function in the synchronized block, and I have set the lock as parameter of synchronized. Why do I still have Exception?
Problem is with your release_lock method. You are reassigning lock to 0 before calling lock.notifyAll(). Which means the notifyAll will be called on a new Integer object which is not locked. Change the code to following to fix the issue.
public static void release_lock() {
synchronized(lock) {
lock.notifyAll();
lock = 0;
}
}
I'm trying to interleave the execution of two independent threads. such that both have a run method with 10 iterations and after every iteration i want to context switch the threads.
thread A starts and after doing something like printing passes control to thread B. then thread B prints and passes control back to A and so on until both finish.
What is the effective mechanism to do this?
I'm attaching a sample code. hope you can help.
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
//SuspendResume.suspendFlag2=false;
SuspendResume.suspendFlag1=true;
while(SuspendResume.suspendFlag1) {
wait();
//System.out.println(SuspendResume.ob1.t.getState().toString());
// if(SuspendResume.ob2.t.getState().toString()=="WAITING")
// SuspendResume.ob2.t.notify();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class NewThread2 implements Runnable {
String name; // name of thread
Thread t;
// boolean suspendFlag;
NewThread2(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
// suspendFlag = false;
t.start(); // Start the thread
}
public String getState()
{
Thread t=Thread.currentThread();
return t.getState().toString();
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(1000);
synchronized(this) {
//SuspendResume.suspendFlag1=false;
//while(SuspendResume.suspendFlag1) {
// while(suspendFlag) {
//wait();
//System.out.println(SuspendResume.ob2.t.getState().toString());
//if(SuspendResume.ob1.t.getState().toString()=="WAITING")
//SuspendResume.ob1.t.notify();
//}
SuspendResume.suspendFlag1=false;
notify();
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
// suspendFlag = true;
}
synchronized void myresume() {
// suspendFlag = false;
notify();
}
}
class SuspendResume {
static boolean suspendFlag1=false;
static NewThread ob1 = new NewThread("One");
static NewThread2 ob2 = new NewThread2("Two");
// static boolean suspendFlag2=false;
public static void main(String args[]) {
try {
//Thread.sleep(1000);
//ob1.mysuspend();
//System.out.println("Suspending thread One");
//Thread.sleep(1000);
//ob1.myresume();
//System.out.println("Resuming thread One");
// ob2.mysuspend();
//System.out.println("Suspending thread Two");
Thread.sleep(1000);
// ob2.myresume();
//System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
System.out.println(ob1.getState());
System.out.println(ob1.getState());
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
First off, I'm not sure what kind of scenario you have where you want to run two threads sequentially over and over again. That sounds like a single thread running two different methods in a loop. None-the-less, it sounds like an interesting challenge so I took it up.
Making use of Java 5's Exchanger class, the solution gets pretty small. I ended up with a single Runnable class. I use two instances of them to pass around a boolean true and boolean false to each other. The Exchanger class facilitates the passing around of the boolean values in a thread safe manner. A Runnable only 'executes' its code when it has the boolean true value.
package interleavedexample;
import java.util.concurrent.Exchanger;
import java.util.logging.Logger;
/**
*
*/
public class InterleavedRunnable implements Runnable {
private final String name;
private final Exchanger<Boolean> exchanger;
private Boolean state;
public InterleavedRunnable(String name, Exchanger<Boolean> exchanger,
Boolean state) {
this.name = name;
this.exchanger = exchanger;
this.state = state;
}
#Override
public void run() {
try {
while (true) {
if (state) {
Logger.getLogger(getClass().getName()).info(name + " is running");
}
state = exchanger.exchange(state);
}
} catch (InterruptedException ex) {
Logger.getLogger(name).info("Interrupted");
}
}
Setting up the runnables are quite easy:
public static void main(String[] args) {
Exchanger<Boolean> exchanger = new Exchanger<Boolean>();
Thread thread1 = new Thread(new InterleavedRunnable("Thread 1", exchanger, true));
Thread thread2 = new Thread(new InterleavedRunnable("Thread 2", exchanger, false));
thread1.start();
thread2.start();
}
Anytime you can find existing functionality within the Java API (or well known libraries), you should utilize them to the fullest extent. The less lines of code you write the less lines there are to maintain.
The 'OS Sycnro 101' solution is to use two semaphores, one for each thread, and swap over one 'GO' token/unit between them. Start both threads and then give the token to whichever thread you want to go first.
Use wait and notify for this.
public class Thread1 implements Runnable {
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("1");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Thread2 implements Runnable{
#Override
public void run() {
while(true){
synchronized (Main.obj) {
try {
Main.obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("2");
synchronized (Main.obj) {
Main.obj.notify();
}
}
}
}
public class Main {
public volatile static Object obj = new Object();
/**
* #param args
*/
public static void main(String[] args) {
Thread t1 = new Thread(new Thread1());
Thread t2 = new Thread(new Thread2());
t1.start();
t2.start();
synchronized (obj) {
obj.notifyAll();
}
}
}
Did not get your question correctly. If you want to execute thread B only after thread A execution is over, then there is no point of multi-threading at all. You can simply put the thread B contents in thread A run() method.
Still if it is very much required then you can try using wait() and notify() methods on two objects . Something like this.
Class ClassA implements runnable{
Message messageA;
Message messageB;
public ClassA(Message messageA,,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop contition;){
//code here
messageB.notify();
messageA.wait();
}
}
}
Class ClassB implements runnable{
Message messageA;
Message messageB;
public ClassB(Message messageA,Message messageB){
this.messageA = messageA;
this.messageB = messageB;
}
public void run(){
for(;loop condition;){
messageB.wait();
//code here
messageA.notify();
}
}
}
now create two objects in main messageA and messageB and pass both of them in the constructor of each thread.