This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Threads and Synchronization and the fly likes Calling wait() when we have obtained two or more locks Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Calling wait() when we have obtained two or more locks" Watch "Calling wait() when we have obtained two or more locks" New topic
Author

Calling wait() when we have obtained two or more locks

John Rushington
Greenhorn

Joined: Jul 01, 2002
Posts: 9
The JLS states that:
The method wait should be called for an object only when the current thread (call it T) has already locked the object's lock. Suppose that thread T has in fact performed N lock actions that have not been matched by unlock actions. The wait method then adds the current thread to the wait set for the object, disables the current thread for thread scheduling purposes, and performs N unlock actions to relinquish the lock. The thread T then lies dormant until one of three things happens:

Now, I understand this business with N lock and N unlock actions, to mean that in the case that I hold multiple locks on the same object, an equal amount of unlock actions will occur when I call wait() on that object, in such a way that when wait() is called (no matter how many locks on that object I have gained), it will become "free (able to be locked by some other thread)" when I perform that single wait() on it.
I also suppose that if I have gained the monitor control (however many "lock actions" that may be) on two (or in the general case, or more) separate objects, and I call wait() off of one of the object references, then I retain control of the other monitor, which practically means that if I call obj2.wait() when I have control of obj1 and obj2 locks, and I intend to be notify()d by another thread when obj2 reaches some state S, but the other thread needs to lock and perform some action on obj1 before notifying me, I will have deadlock (of at least those two threads involved).
So I have two questions: 1: am I correct in assuming that no matter how many lock actions I perform on one object, a single wait() performed on that object (by the same thread, of course) will release the object so that other threads can lock it, and 2: that holding locks on multiple objects and then waiting on one of them will retain the locks on the others?
Thanks,
John
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Originally posted by John Rushington:
The JLS states that:

So I have two questions: 1: am I correct in assuming that no matter how many lock actions I perform on one object, a single wait() performed on that object (by the same thread, of course) will release the object so that other threads can lock it, and 2: that holding locks on multiple objects and then waiting on one of them will retain the locks on the others?
Thanks,
John

Hi John,
It's important to make the distinction here between owning a lock and performing a lock action: you can't perform a lock action, it's done on your behalf. I suspect that you know this, based on the depth of your question, but I wanted to clear in our terminology.
In the case of 1) Yes, you're absolutely correct. No matter how many locks a given thread has achieved on a given object, they are all released when wait successfully executes. Otherwise, no other synchronized thread could modify the object, and we know that this is not the case.
2) You're also right here. Obtaining a lock on a given object and releasing that lock has nothing to do with any other locks. A corollary to this is the fact that locking a given object does not lock the member variables of that object. This is easy enough to test in Java 1.4, which contains a holdsLock(Object) method on the Thread object.
HTH,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4


Java Regular Expressions
John Rushington
Greenhorn

Joined: Jul 01, 2002
Posts: 9
Then I suppose it would be correct to say that "The first successful lock action (done on your behalf by the VM, where a single lock action is equal to successfully entering a synchronized block or synchronized method, whether or not you already have performed a lock action on that object) corresponds to obtaining the lock on an object (and each object has associated with it a single lock). All "unlock actions" on a given object are performed with a single wait() call on that object"?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Yes, that's correct. After the first lock action, successive lock actions on the same lock are simply... errr... emphasizing it. And for unlock actions, only the last one (where number of unlock actions = number of lock actions) actually releases the lock.
A single wait() call performs all required unlock actions to release the lock on the monitor. And when notify() is called and the thread is reactivated, there will be an equal number of lock actions performed, effectively returning the lock status to exactly what it was before the wait().


"I'm not back." - Bill Harding, Twister
Max Habibi
town drunk
( and author)
Sheriff

Joined: Jun 27, 2002
Posts: 4118
Just to be clear here: you can, and do, obtain multiple locks on a given object. For example, if you call a synchronized method from another synchronized method.
Best regards,
M, author
The Sun Certified Java Developer Exam with J2SE 1.4
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Calling wait() when we have obtained two or more locks
 
Similar Threads
object.wait()
Synchronization
wait()
Dan's: Blocked vs Waiting - possible mistake
Basic thread doubt