Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why wait/notify/notifyAll methods are not synchronized in java ?

Tags:

in Java whenever we need to call wait/notify/notifyAll, we need to have access to object monitor (either through synchronized method or through synchronized block). So my question is why java didn't go for synchronized wait/notify methods removing the restriction of calling these methods from synchronized block or methods.

In case these are declared as synchronized, it would have automatically taken the monitor access.

like image 709
Ashish Avatar asked Aug 11 '11 01:08

Ashish


People also ask

Why wait () notify () and notifyAll () methods have to be called from a synchronized method or block?

Calling notify() or notifyAll() methods issues a notification to a single or multiple threads that a condition has changed and once the notification thread leaves the synchronized block, all the threads which are waiting for fight for object lock on which they are waiting and lucky thread returns from wait() method ...

Why wait () notify () and notifyAll () methods are in object class and not in thread class?

If wait() and notify() were on the Thread instead then each thread would have to know the status of every other thread and there is no way to know thread1 that thread2 was waiting for any resource to access. Hence, notify, wait, notifyAll methods are defined in object class in Java.

Can we use wait and notify without synchronized?

If you need to call wait(), notify(), or notifyAll() from within a non-synchronized method, then you must first obtain a lock on the object's monitor. If you don't, an exception will be generated when an attempt is made to call the method in question.

What is the purpose of wait () notify () notifyAll () in Java?

The wait() method causes the current thread to wait until another thread invokes the notify() or notifyAll() methods for that object. The notify() method wakes up a single thread that is waiting on that object's monitor. The notifyAll() method wakes up all threads that are waiting on that object's monitor.


1 Answers

For notify and notifyAll, the problem with your idea is that when you notify you also have other stuff you're typically doing in the same synchronized block. So making the notify method synchronized wouldn't buy you anything, you'd still need the block. Likewise wait has to be in a synchronized block or method in order to be useful, such as being inside a spinlock where the test has to be synchronized anyway. So the granularity of locking is all wrong for what you suggest.

Here's an example, this is about the simplest queue implementation you can have in Java:

public class MyQueue<T> {      private List<T> list = new ArrayList<T>();      public T take() throws InterruptedException {         synchronized(list) {             while (list.size() == 0) {                 list.wait();             }             return list.remove(0);         }     }      public void put(T object) {         synchronized(list) {             list.add(object);             list.notify();         }     } } 

So you can have producer threads that add things to the queue and consumer threads that take things out. When a thread goes to get something out of the queue it needs to check within the synchronized block that there's something in the list, and once it's been notified it needs to reacquire the lock and make sure there is still something in the list (because some other consumer thread could have stepped in and grabbed it).There's also the "spurious wake-up" phenomenon: you can't rely on getting woken up as sufficient evidence that something happened, you need to check that whatever condition you're waiting for is actually true, and that needs to be done within the synchronized block.

In both of these cases, checks surrounding the wait need to be made with the lock held so that when the code takes action based on those checks it knows that those results are currently valid.

like image 137
Nathan Hughes Avatar answered Oct 19 '22 22:10

Nathan Hughes