Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java: If notify() is always called before the lock release, how could a waiting threads acquire this same lock?

I think that I already know the answer to that question, however, I would like to read your opinions to make sure that I really understand how java thread's state machine (or diagram) works.

Imagine that Thread A runs the notify() just before return a given value:

public class baz{

    // Thread B runs this:
    public synchronized void bar(){
       wait();
    } 

    // Thread A runs this:
    public synchronized int foo(){
       notify();
       return 11;
    }
}

notify() will be called before Thread A releases the lock (that will occurs "after" the return 11; statement). So, how could a Thread B, that is waiting for this lock (via wait() method), acquire the lock that is still held by Thread A? Note that, when thread B is notified the lock has not yet been released by Thread A.

So what I think of this situation is the following:

After calling wait(), Thread B will change its state from Running to Waiting. After receiving the notification (from Thread A notify() method), Thread B will return from wait(), change its state to Runnable and try to acquire the lock. Since the lock is not yet released by Thread A, Thread B will be blocked on the object's monitor and pass its state from Runnable to Blocked. Eventually, after Thread A releases the lock, Thread B will acquire the lock and pass its state from Blocked to Running.

Is this right? What I want to understand with this question is what happens to a thread that returns from a wait() which is synchronized by an already acquired lock.

like image 641
Diogo Anjos Avatar asked Nov 02 '14 16:11

Diogo Anjos


1 Answers

Yes, your explanation is correct.

When you call wait() on an object, the calling thread will be added to the object's wait set. When it is notify()ied, it will be removed from that wait set, and perform a lock action on the object (it's within a synchronized block on that object). That lock action will block the current thread until it is complete, ie. locked the object monitor.

This is the exact same behavior that two threads would have when trying to enter a synchronized block on the same object. The first thread to reach would lock the object monitor, completing the lock object immediately. The other thread blocks until its lock action is complete, ie. after the first thread unlocks the monitor.

like image 141
Sotirios Delimanolis Avatar answered Oct 05 '22 18:10

Sotirios Delimanolis