Why isn't Object.notify() a synchronized method?

Brian Goetz brian.goetz at oracle.com
Thu Jun 4 00:14:19 UTC 2015


The performance issue here is mostly a red herring.

The reason notify() is not synchronized has much more to do with 
correctness; when you "forget" to wrap your notify call with lock 
acquisition, it is almost always a bug.  (The rest of this explanation 
is probably clearer if you've read JCiP Ch14.)

A thread calls notify/notifyAll if it has effected a state change that 
could cause a waiting thread to become unblocked.  Blocking is generally 
associated with a state predicate ("queue is nonempty", "light is 
green"), which refers to some state, and that state needs to be guarded 
by the lock associated with the condition queue.  If you've modified the 
state that underlies the predicate (i.e., you put something in the 
queue, or switched the light to green), you needed the lock anyway.

(Because spurious wakeup is allowed, even the trivial cases like a 
one-shot "release all threads when timer expires" are better implemented 
with a boolean state predicate (or better, CountDownLatch) than simply 
calling notifyAll.)

So, while its not out of the question that code that wants to call 
notify without locking isn't wrong, it probably is wrong, and having the 
library "conveniently" acquire the lock for you is just brushing the 
mistake under the rug.

On 5/29/2015 12:48 PM, Ulf Zibis wrote:
> Thanks for your hint David. That's the only reason I could imagine too.
> Can somebody tell something about the cost for recursive lock
> acquisition in comparison to the whole call, couldn't it be eliminated
> by Hotspot?
>
> As I recently fell into the trap of forgetting the synchronized block
> around a single notifyAll(), I believe, the current situation is just
> errorprone.
>
> Any comments about the Javadoc issue?
>
> -Ulf
>
>
> Am 28.05.2015 um 18:27 schrieb David M. Lloyd:
>> Since most of the time you have to hold the lock anyway for other
>> reasons, I think this would generally be an unwelcome change since I
>> expect the cost of recursive lock acquisition is nonzero.
>>
>> On 05/28/2015 11:08 AM, Ulf Zibis wrote:
>>> Hi all,
>>>
>>> in the Javadoc of notify(), notifyAll() and wait(...) I read, that this
>>> methods should only be used with synchronisation on it's instance.
>>> So I'm wondering, why they don't have the synchronized modifier out of
>>> the box in Object class.
>>>
>>> Also I think, the following note should be moved from wait(long,int) to
>>> wait(long):
>>> /The current thread must own this object's monitor. The thread releases
>>> ownership of this monitor and waits until either of the following two
>>> conditions has occurred://
>>> /
>>>
>>>   * /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 timeout period, specified by timeout milliseconds plus nanos
>>> nanoseconds arguments, has
>>>     elapsed. /
>>>
>>>
>>>
>>> Cheers,
>>>
>>> Ulf
>>>
>>
>


More information about the hotspot-compiler-dev mailing list