views:

94

answers:

3

I've read many docs about thread states, some of them tells that there is two different states: blocked (before synchronized) and wait (if calls wait), some others are telling that there is only one state: wait. Moreover, some docs telling that you should call notify() for every wait() and if you don't then threads waiting() will never be eligible for execution even if monitor is unlocked.

+1  A: 

Standard doc is here

When a thread calls Object.wait method, it releases this acquired monitor and is put into WAITING (or TIMED_WAITING if we call the timeout versions of the wait method) state. Now when the thread is notified either by notify() or by notifyAll() call on the same object then the waiting state of the thread ends and the thread starts attempting to regain all the monitors which it had acquired at the time of wait call. At one time there may be several threads trying to regain (or maybe gain for the first time) their monitors. If more than one threads attempt to acquire the monitor of a particular object then only one thread (selected by the JVM scheduler) is granted the monitor and all other threads are put into BLOCKED state.

org.life.java
why do you think 'Object.wait' releases 'all' the threads acquired monitors? I think it releases only that 'Object's lock. I've read that somewhere but don't remember where.
gasan
@gasan I meant it releases all of its acquired locks,
org.life.java
yes, that's exactly what I'm asking about. Why do you mean it releases `all` locks. I think it releases only this particular monitor lock.
gasan
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#wait(long, int)
org.life.java
`The thread releases ownership of this monitor ` only `this ` monitor, not ` all`
gasan
@gasan my mistake
org.life.java
+1  A: 

There are two different states BLOCKED and WAITING.

The part about waiting forever if no one notifies (or interrupts) you is true.

Thilo
Many thanks for the link
gasan
+8  A: 

From you last sentence I see you don't fully understand the difference between synchronized and wait()/notify().

Basically, monitor has lock and condition. It's almost orthogonal concepts.

  • When thread enters a synchronized block, it acquires a lock. When thread leaves that block, it releases a lock. Only one thread can have a lock on a particular monitor.

  • When thread having a lock calls wait(), it releases a lock and starts waiting on its condition. When thread having a lock calls notify(), one of the threads (all threads in the case of notifyAll()) waiting on the condition becomes eligible for execution (and starts waiting to acquire a lock, since notifying thread still has it).

So, waiting to acquire a lock (Thread.State.BLOCKED) and waiting on the monitor's condition (Thread.State.WAITING) are different and independent states.

This behaviour becames more clear if you look at Lock class - it implements the same synchronization primitives as synchronized block (with some extensions), but provides clear distinction between locks and conditions.

axtavt
do you mean, that notify() changes the condition of the monitor? But what notifyAll() does then? Does this mean that monitor has an array of conditions, one for every thread it controls. Also, how thread is checking for the condition or lock, does it checks in infinite loop (while !monitor.lock) or (while !monitor.condition[threadNum])? P.S. here I'm talking about simple monitors (Object), I'm not familiar with high-level concurrent mechanisms (does anyone use them?)
gasan
@gasan: Monitor's condition is not a condition in normal sense, it's a synchronization primitive, so it can't be changed. It just have a set of threads waiting on it. `notifyAll()` works the same way as `notify()`, but for all threads waiting on condition.
axtavt