问题
I just have a question in regards to threads that run concurrently and the lock they have on an object. From what I understand is that the thread that calls the wait() method will go on a waiting list and allows another thread from a blocked list to take over the lock on and object(within synchronized code). If this thread that now has the lock on the object calls the notify() method it wakes up the thread that called wait() and it is moved to the blocked list.
What happens to the thread that calls the notify() method. Does it still have a lock on the object or does it now go on a waiting list?
regards
回答1:
Only one thread can hold the lock for an object. The wait()
and notify()
methods must be called while the thread holds the lock on the object you call these methods on; if they don't (for example, because you didn't synchronize on the object), you'll get an IllegalMonitorStateException
.
When you call wait()
, then the thread gives up the lock and goes on a waiting list (stops executing). When wait()
returns, the thread will have obtained the lock again. However, the thread that calls notify()
is still holding the lock, so the waiting thread will not resume before the notifying thread exits the synchronized
block or method so that it releases the lock on the object.
By calling notify()
the thread is not giving up the lock on the object.
A possible sequence of events would be:
- Thread 1 goes into a
synchronized
block, obtaining the lock for the object - Thread 1 calls
wait()
on the object, giving up the lock, stops executing - Thread 2 goes into a
synchronized
block, obtaining the lock for the object - Thread 2 calls
notify()
on the object, but still holds the lock - Thread 1 is awakened and tries to obtain the lock, but it can't because Thread 2 still has it (so Thread 1 has to wait for the lock)
- Thread 2 exits the
synchronized
block and releases the lock - Thread 1 can now obtain the lock and returns from
wait()
回答2:
The notifying thread still owns the lock. See doc section 17.14 (bottom of the page):
The notify method should be called for an object only when the current thread has already locked the object's lock. If the wait set for the object is not empty, then some arbitrarily chosen thread is removed from the wait set and re-enabled for thread scheduling. (Of course, that thread will not be able to proceed until the current thread relinquishes the object's lock.)
回答3:
No, it will release the lock by leaving a synchronized block or returning from a synchronized method. It will not go back to the waiting list until calling wait()
again.
来源:https://stackoverflow.com/questions/8999707/understanding-multi-threading