Reputation: 2699
I have code that I checked and I just want to know my understanding is correct. I have following two classes
public class WaitCheckWaiter implements Runnable
{
WaitCheck wc;
public WaitCheckWaiter( WaitCheck wc )
{
this.wc = wc;
}
@Override
public void run()
{
synchronized ( wc.strList )
{
wc.strList.add( "Added" );
System.out.println( "Notify for others" );
wc.strList.notifyAll();
for ( int i = 0; i < 100; i++ )
{
System.out.println( i );
}
try
{
Thread.sleep( 5000 );
}
catch ( InterruptedException e )
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println( "Woke up" );
System.out.println( "After Notifying" );
}
System.out.println( "After synch WaitCheckWaiter" );
}
}
and then this one below
public class WaitCheck implements Runnable{
WaitCheck wc;
List<String> strList = new ArrayList();
public static void main(String[] args) {
WaitCheck wc = new WaitCheck();
new Thread(wc).start();
WaitCheckWaiter wcw = new WaitCheckWaiter(wc);
new Thread(wcw).start();
}
@Override
public void run() {
synchronized (strList) {
if(strList.size() == 0)
{
try {
System.out.println("Just Before wait..");
strList.wait();
System.out.println("Just after wait..");
// printing the added value
System.out.println("Value : "+strList.get(0));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
System.out.println("In else statement..!!");
}
}
System.out.println("After synch WaitCheck");
}
}
So my understanding is even if I call the notifyAll(), the waiting thread cannot resume until the synchronized block is finished which called the notifyAll(). Is this right or are there any other none deterministic behavior.
Upvotes: 0
Views: 57
Reputation: 27115
In most operating systems, a thread is represented by an object that can be moved around between different containers depending on its state. These containers traditionally are called "queues" even though they are not necessarily implemented as actual, first-in-first-out queues.
When a thread calls o.wait()
, it's object gets moved from a "currently running" queue to a queue that holds only those objects that are awaiting o.notify()
. When another thread calls o.notify()
the operating system selects one thread from that queue, and moves it to the queue of threads that are waiting their turn to enter (or return to) a synchronized(o)
block.
That's pretty much the only thing that o.notify()
does. In fact, if the queue of threads that are awaiting o.notify()
is empty, then o.notify()
does not do anything at all.
o.notifyAll()
is the same, except that instead of moving just one thread, it moves all of the threads that are waiting.
Upvotes: 1
Reputation: 18408
Adding to the other answer, from the doc about Thread.sleep(...) :
The thread does not lose ownership of any monitors.
Meaning that at least as a basic principle, one should never ever invoke Thread.sleep(...) as long as any sync locks are still being held.
Upvotes: 0
Reputation: 31279
The Javadoc for the Object.notifyAll
method is pretty clear on this topic :
(text bolded by me)
Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object. The awakened threads will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened threads enjoy no reliable privilege or disadvantage in being the next thread to lock this object.
Upvotes: 3