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