A Java Threading wait() and Notify() seems to work peculiarly - java

class myThreadRun implements Runnable
{
public void run() {
roo();
}
public synchronized void roo()
{
System.out.println("In thread before wait " + Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n"+Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
//notify();
}
public synchronized void foo()
{
notify();
}
}
public class ThreadingDemo {
public synchronized void Start()
{
System.out.println("Labamba");
myThreadRun mThRun = new myThreadRun();
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//mThRun.foo(); //This works
//mThRun.notify(); //crash
//thread.notify();//crash
try {
thread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new ThreadingDemo().Start();
}
This is simple code to demonstrate wait() and notify(),
In the myThreadRun class run() method just does wait() and foo() method does notify()
as indicated in the code above, if I do mThRun.notify() the program crashes, but mThRun.foo() runs the without a hitch and gives the much needed result. I need to know why?

You need to own the monitor for the object to all obj.wait() and obj.notify().
That is why it works when called within the synchronized block on mThRun but not outside. So if you put the mThRun.notify(); in a synchronized block, it works, like this:
synchronized (mThRun) {
mThRun.notify();
}

In your case you are getting an IllegalMonitorStateException.
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Put another way, you don't hold the lock of the object you are trying to notify. Having the lock of a different object doesn't help.
When you use notify() and wait() you need to change a state and check for it. If you don't do this, you can find that either
notify() is called before wait() and the signal is lost
wait() wakes prematurely
You cannot assume notify/wait is a reliable messaging protocol.
I suggest you consider using the concurrency library which is a better choice in most cases from Java 5.0 (2004)

May be you are going very hard with wait/notify. Its very simple. what you need to know is which object is used for monitor lock. To make the same code working i have modified the same code: ( I have put MAK comment where i changed the code, hope its helpful)
class MyThreadRun implements Runnable {
public void run() {
roo();
}
public synchronized void roo() {
System.out.println("In thread before wait " + this);
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
JOptionPane.showMessageDialog(null, "After wait in\n" + Thread.currentThread().getName());
System.out.println("In thread after wait " + Thread.currentThread().getName());
}
}
public class ThreadingDemo {
public static void main(String[] args) {
MyThreadRun mThRun = new MyThreadRun();
System.out.println("Labamba: " +mThRun);
Thread thread = new Thread(mThRun);
thread.start();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//mThRun.foo(); //This works //MAK: no sense
//mThRun.notify(); //crash //MAK: Need monitor lock
synchronized (mThRun) {
mThRun.notify();//crash //MAK: will work now
}
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Related

Unexpected exception occurs during producer/consumer code in Java

I was looking at a producer-consumer example with wait and notify, even though it works some times it gives exception. Not able to figure out where the problem is.
Exception in thread "Thread-5" java.util.NoSuchElementException at
java.util.LinkedList.removeFirst(Unknown Source) at com.bhatsac.workshop.producerconsumer.ProdNConsumer.consumer(ProdNConsumer.java:55)
at com.bhatsac.workshop.producerconsumer.ProdConsumerInvoker.lambda$5 (ProdConsumerInvoker.java:35)
at java.lang.Thread.run(Unknown Source)
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;
public class ProdNConsumer {
LinkedList<Integer> list = new LinkedList<Integer>();
private int LIMIT = 1;
private volatile boolean shutdown = false;
private AtomicInteger counter=new AtomicInteger(0);
private Object lock=new Object();
public void produce() {
while (true) {
synchronized(lock){
System.out.println("In producer :)"+ list.size());
if(this.list.size()==this.LIMIT){
try {
System.out.println("In waiting state producer");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced by thread= "+ Thread.currentThread().getName());
list.add(counter.getAndIncrement());
System.out.println("Going to sleep for a while");
lock.notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void consumer() {
while (true) {
synchronized(lock){
System.out.println("In consumer :)");
if(list.size()==0){
try {
System.out.println("In waiting state consumer");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("consumed by thread="+ Thread.currentThread().getName());
list.removeFirst();
lock.notifyAll();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ProdConsumerInvoker {
public static void main(String[] args) {
ProdNConsumer pc= new ProdNConsumer();
Thread tc1=new Thread(()->{pc.consumer();});
new Thread(()->{pc.produce();}).start();
new Thread(()->{pc.produce();}).start();
Thread tp1=new Thread(()->{pc.produce();});
new Thread(()->{pc.consumer();}).start();
new Thread(()->{pc.consumer();}).start();
tp1.start();
tc1.start();
}
}
Your producer and consumer threads are using the same lock. When a consumer wakes up and consumes an element, it calls lock.notifyAll(), which will wake up all consumers and producers waiting on it. Another consumer wakes up thinking there are items in the list, but it removes the first item from an empty list, causing the exception.
In the consumer, instead of if(list.size()==0), use while(list.size()==0). Similar reasoning applies to the producer as well. Just because the thread woke up doesn't mean that the condition it is waiting on is true. It only means that before the thread woke up the condition was true. It must check it again.

Threads producer consumer in java

Below is the consumer producer problem code, but the code is not working as expected. Here the consumer and producer are supposed to be just producing and consuming one object.
public class ProducerConsumer {
private static LinkedList<Integer> linkedList = new LinkedList<>();
public static void main(String a[]) throws InterruptedException {
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized(this) {
while (linkedList.size() == 1) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized(this) {
while (linkedList.isEmpty()) {
try {
wait();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
notify();
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
We get the output as : Produced
And the program hangs.
Please help with possible solutions/ explanations
Use a shared lock. In the posted code each Runnable is using itself as a lock so no actual locking takes place.
When a thread waits, another thread needs to call notify on the same lock in order to wake up the waiting thread. We know from your logging that the Producer thread does its thing, but since the notify acts on a lock that is not the same as the one the Consumer is using, the consumer thread never wakes up.
Changing the code to use a shared lock works:
import java.util.*;
public class ProducerConsumer { private static LinkedList linkedList = new LinkedList();
public static void main(String a[]) throws InterruptedException {
final Object lock = new Object();
Thread producer = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
while (linkedList.size() ==1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produced");
linkedList.add(1);
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Thread consume = new Thread(new Runnable() {
#Override
public void run() {
// produce
synchronized (lock) {
while (linkedList.isEmpty()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumed");
linkedList.removeFirst();
lock.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
producer.start();
consume.start();
producer.join();
consume.join();
}
}
Output for this is:
c:\example>java ProducerConsumer
Produced
Consumed
which I think is what you're expecting.
Btw see this other answer I wrote for a dirt-simple implementation of a queue; you are better off protecting the shared data structure than putting the code in the threads accessing the data structure, especially look at how much easier the code is to write.
Concurrency means that you can not know before runtime which Thread will end first. So you can not know which of the Consumer and Producer is launched, executed or finished first.
To help you, you can use a cyclic barrier https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html or applying the Fork/Join Framework https://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Your synchronized blocs just say : only one Thread at a time can execute this part of code, not execute the first and the second after.
An example of how CyclicBarrier works :
service = Executors.newFixedThreadPool(numThreadsTotal);
CyclicBarrier c = new CyclicBarrier(numThreadsToWait);
runProducer();
c.await();
runConsumer();
It will wait until the there is as much Threads as numThreadsToWait that have execute the runProducer to execute the runConsumer().
Perhaps using a Thread Pool with a size of 1 could help you, but you will loose the benefits of concurrency.
I think best what you can do, is use BlockingQueue.

Cyclic barrier await method not working

I am trying to learn multithreading and was trying with a cyclic barrier. I understand that to break the barrier an await method must be called by the number of the thread mentioned while creating the barrier. I am trying to do the same but when I check if the barrier is broke my main method is going in an infinite loop.
class CyclicBarrierTrial implements Runnable{
CyclicBarrier barrier;
public CyclicBarrierTrial(CyclicBarrier barrier){
this.barrier=barrier;
}
public void run() {
System.out.println("in the run method");
try {
Thread.sleep(1000);
System.out.println("going to call awake on barrier"+ Thread.currentThread().getName());
try {
barrier.await();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("barrier broke");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println("Wake up from the Sleep"+ Thread.currentThread().getName());
}
}
public class MYCountDownLatch {
public static void main(String[] args) throws InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(2);
Thread t1= new Thread(new CyclicBarrierTrial((barrier)));
t1.start();
Thread t2= new Thread(new CyclicBarrierTrial((barrier)));
Thread.sleep(2000);
t2.start();
while(!barrier.isBroken())
{
System.out.println("waiting for the barrier to break "+barrier.isBroken());
}
System.out.println("MAIN THREAD finally barrier to broke ");
}
}
barrier.isBroken() indicates if barrier is in broken state, which is different than barrier is tripper.
To check this, you can try interrupting one of thread, this will raise BarrierBrokenException on other threads and barrier.isBroken() will be true.
Thread.currentThread().interrupt();
If you want to wait for all threads to complete, then you can use ExecutorService.awaitTermination or Thread.join
From documentation:
If any thread is interrupted while waiting, then all other waiting threads will throw BrokenBarrierException and the barrier is placed in the broken state.
Hope this help.

Wait And Notify IllegalMonitorStateException Anonymous Class

According to How to use wait and notify in Java? I have to synchronized on the same object to call notify.
I have synchronized on the same haveCoffee object. Why I am getting IllegalMonitorStateException when I call the notify method ?
I am Sleeping
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.example.concurrent.basic.WaitAndNotify$2.run(WaitAndNotify.java:42)
in the following code:
public class WaitAndNotify {
public static void main(String[] args) {
Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
On the first Thread, you call wait on an object while having its monitor (the object being this haveCoffee).
However, on the second thread, you call notify() on me, while having the monitor of haveCoffee.
This should work:
public class WaitAndNotify {
public static void main(String[] args) {
final Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
From oracle documentation page,
public class IllegalMonitorStateException
extends RuntimeException
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
Whenever you get this exception, just go through your code and check wait() and notify() calls and the object on which these calls have been invoked. You can easily figure out what went wrong.
EDIT:
wait() or notify() calls have to be invoked on object once you get monitor on that object.
You should be calling
haveCoffee.notify()
instead of just
notify().
If you invoke just notify() it calls the notify() method on the this object which is the second thread me where as you have synchronized on haveCoffee thread and that is the reason for exception you are seeing.
So the code in thread2 me should looks like:
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Call to Java Object's wait() breaks thread synchronization

public class Main2 {
public static void main(String[] args) {
new Test2().start();
new Test2().start();
}
}
class Test2 extends Thread {
#Override
synchronized public void run() {
try {
System.out.println("begin wait");
wait();
} catch (Exception ex) {
}
}
}
As the actual result of running the test:
begin wait,
begin wait,
two times from the two threads.
Contrast to the expected result:
begin wait,
only one time from one of the two threads because wait() is called inside the synchronized run() method.
Why could call to Object's wait() break thread synchronization?
Thans a lot!
public class Main3 {
public static void main(String[] args) {
Test3 t = new Test3();
new Thread(t).start();
new Thread(t).start();
}
}
class Test3 implements Runnable {
synchronized public void run() {
try {
System.out.println("begin wait");
wait();
} catch (Exception ex) {
}
}
}
#akf & #Sean Owen
Thanks for your replies. Sorry for my mistake, now i modified the code to place the synchronization on the same object's run(), the result remained: begin wait, begin wait, two times.
#akf
wait will release the lock that
synchronize has grabbed, and will be
re-gotten once the thread is notified.
Could you elaborate a little bit?
The object that you are synchronizing on in this example is not the class, but the instance, so each new Test2 object would be synchronizing on a different monitor.
The method you might be looking for here is sleep, not wait. wait will release the lock that synchronized has grabbed, and will be re-gotten once the thread is notified.
Note that for your test to work correctly, you will need to lock on a common object. If you want to see wait in action, I have thrown together a simple app that will pop up a frame with a "Notify" button. Two threads will be started that wait on a common object and are in turn notified when the button is pressed.
public static void main(String[] args)
{
final Object lock = new Object();
final JFrame frame = new JFrame("Notify Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Notify");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent evt) {
synchronized(lock) {
lock.notify();
}
}
});
frame.add(button);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.setVisible( true );
}
});
new Thread(new Runnable() {
public void run() {
synchronized(lock) {
try {
System.out.println("1. starting");
lock.wait();
System.out.println("1. step 1");
lock.wait();
System.out.println("1. step 2");
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
synchronized(lock) {
try {
System.out.println("2. starting");
lock.wait();
System.out.println("2. step 1");
lock.wait();
System.out.println("2. step 2");
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}).start();
}
For a simple explanation of wait, the JavaDoc is always a good place to start:
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
You have two different Test2 objects. Synchronized methods lock on the object. They are not acquiring the same lock, so no it should print twice.
an simple example that can help you is this:
public class test {
public static void main(String[] args) {
Prova a=new Prova();
new Test2(a).start();
new Test2(a).start();
}
}
class Prova{
private boolean condition;
public void f(){
while(condition){
//Thread.currentThread Returns a reference to the currently executing thread object.
//Thread.getName() return name Thread
System.out.println(Thread.currentThread().getName()+" begin wait");
try{
wait();
}catch(InterruptedException c){return;}
}
System.out.println(Thread.currentThread().getName()+" first to take the mutex");
condition=true;
}
}
class Test2 extends Thread {
private Prova a;
private static boolean condition;
public Test2(Prova a){
this.a=a;
}
#Override
public void run() {
synchronized(a){
try {
a.f();
} catch (Exception ex) {
}
}
}
}
in this case the two threads synchronize an object, the first taking the lock release message, the second one waits. in this example uses the condition variable
summary to wait/notify mechanism:
1)current thread reaches one object's synchronized code block which contains the call to wait(), it competes with other threads for the lock(the object's monitor), as winner it executes the block till the call to wait() encounters.
2)by calling wait(), current thread releases the lock to other competing threads, then halts execution, wait for notify being sent from another thread who succeeds in obtaining the lock.
JavaDoc:
A thread becomes the owner of
the object's monitor in one of three
ways:
•By executing a synchronized instance
method of that object.
•By executing
the body of a synchronized statement
that synchronizes on the object.
•For
objects of type Class, by executing a
synchronized static method of that
class.
3)another thread reaches the same object's yet another synchronized code block which contains the call to notify/notifyAll(), it competes with other threads for the lock, as winner it executes the block till finishing the call to notify/notifyAll(). It will release the lock either by call to wait() or at the end of the execution on the block.
4)upon receiving notify/notifyAll(), current thread competes for the lock, as winner the execution continues where it has halted.
simple example:
public class Main3 {
public static void main(String[] args) {
Test3 t = new Test3();
new Thread(t).start();
new Thread(t).start();
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
t.testNotifyAll();
}
}
class Test3 implements Runnable {
synchronized public void run() {
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock");
try {
wait();
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "wait block got the lock again");
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye wait block");
}
synchronized void testNotifyAll() {
System.out.println(Thread.currentThread().getName() + ": " + "notify block got the lock");
notifyAll();
System.out.println(Thread.currentThread().getName() + ": " + "notify sent");
try {
Thread.sleep(2000);
} catch (Exception ex) {
}
System.out.println(Thread.currentThread().getName() + ": " + "bye notify block");
}
}
output:
Thread-0(or 1): wait block got the
lock
Thread-1(or 0): wait block got
the lock
main: notify block got the
lock
main: notify sent
main: bye notify block
Thread-0(or 1): wait block
got the lock again
Thread-0(or 1): bye
wait block
Thread-1(or 0): wait block
got the lock again
Thread-1(or 0): bye
wait block

Categories

Resources