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

2015-06-03 Thread Andreas Lundblad
On Sun, May 31, 2015 at 02:31:25PM +1000, David Holmes wrote:
 As I recently fell into the trap of forgetting the synchronized block
 around a single notifyAll(), I believe, the current situation is just
 errorprone.
 
 How is it errorprone? You forgot to acquire the lock and you got an
 IllegalMonitorStateException when you did notifyAll. That's pointing
 out your error.


The reason for not making wait/notify synchronized is *not* that it would be 
unnecessary because you typically already hold the lock anyway. The reason is 
(as David Holms pointed out earlier) that it would be *meaningless* to make 
them synchronized.

When you say it's errorprone it sounds like you first had

notifyAll();

and then fixed the IllegalMonitorStateException by doing

synchronized (this) {
notifyAll();
}

(and then wrote your original email asking why notifyAll didn't do this on the 
inside).

If this is the case you have not understood the intention of using synchronized 
here. In a nutshell wait and notify is all about thread communication, and for 
that to work correctly you need to synchronize your execution. Let me try to 
explain why wrapping *just* notifyAll() in a synchronized block (or relying on 
making notifyAll synchronized) is broken: Suppose you have a producer / 
consumer thing going on. In produce() you have something like

enqueue(value);
synchronized (this) {
notifyAll(); // because consumer may be waiting for a value
}

and in consume() you have something like

synchronized (this) {
while (noValueIsAvailable())
wait();
}
value = retrieve();

Suppose now that ProducerThread enters produce(), enqueues a value and before 
reaching notifyAll, ConsumerThread comes along, enters consume(), consumes the 
value, processes the value, calls consume *again*, sees that noValueIsAvailable 
and calls wait. ProducerThread now continues it's execution and calls 
notifyAll(). ConsumerThread is woken up, but at this point no value is 
available despite there was a call to notify! (In the best case, this doesn't 
crash the program, in worst case, ProducerThread assumed that the value should 
be processed after notifyAll, in which case you may run into a deadlock. If 
there were more variables involved you could also have memory visibility issues 
involved and accidentally break class invariants by doing this.)

I've written an answer to a similar question here:

Why must wait() always be in synchronized block
http://stackoverflow.com/a/2779674/276052

best regards,
Andreas


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

2015-05-30 Thread David Holmes

On 30/05/2015 2:48 AM, 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?


There are a number of fast paths related to recursive locking. Not sure 
if inlining allows lock elision that something for the compiler folk.



As I recently fell into the trap of forgetting the synchronized block
around a single notifyAll(), I believe, the current situation is just
errorprone.


How is it errorprone? You forgot to acquire the lock and you got an 
IllegalMonitorStateException when you did notifyAll. That's pointing out 
your error.



Any comments about the Javadoc issue?


I did comment - I don't see any issue.

David H.



-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







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

2015-05-29 Thread Ulf Zibis

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







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

2015-05-28 Thread David Holmes

On 29/05/2015 2: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.


Because, as others have said, the way you use a monitor is to acquire 
the monitor lock, then inspect/modify mutable object state, then do a 
wait/notify/notifyAll as appropriate, and finally release the monitor. 
Making the methods themselves synchronized would be useless from a 
synchronization correctness perspective and would prevent coding errors 
from resulting in IllegalMonitorStateException.



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. /


Why would you move it when wait(long) already has the more detailed:

 * p
 * The current thread must own this object's monitor.
 * p
 * This method causes the current thread (call it varT/var) to
 * place itself in the wait set for this object and then to relinquish
 * any and all synchronization claims on this object. Thread varT/var
 * becomes disabled for thread scheduling purposes and lies dormant
 * until one of four things happens:
 ...


David
-




Cheers,

Ulf



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

2015-05-28 Thread Vitaly Davidovich
What would synchronized on that method help with? Typically you do
something while holding the lock and then notify while still holding the
lock.

sent from my phone
On May 28, 2015 12:09 PM, Ulf Zibis ulf.zi...@cosoco.de 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




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

2015-05-28 Thread Aleksey Shipilev
On 05/28/2015 07:08 PM, 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.

Well, at least synchronized wait() would be very odd, since it
actually relinquishes the monitor. This will pose an interesting
paradox: if wait() is claimed to be synchronized, but notify() requires
acquiring the same monitor, how would any object be notified, ever?

But really, I'd think this serves the purpose of waking up with all
the appropriate locking state preserved. E.g. making sure only one
thread owns the object monitor, and it reenters back right where it
had left at wait() in the synchronized section.

Thanks,
-Aleksey



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

2015-05-28 Thread 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



--
- DML


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

2015-05-28 Thread Ulf Zibis

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