-1

if i have the below piece of code

synchronized (this)
{
    System.out.println("Waiting for return key.");
    scanner.nextLine();
    System.out.println("Return key pressed.");
    notify();
    Thread.sleep(5000);
}

After notify, I am calling sleep which means, I have notified the waiting thread but not relinquished the lock, what happens now.. After notifying the waiting thread would have been woken up but not able to acquire the lock, so from here on-wards, is it a busy wait? since we are not going to call notify again.

Same question goes with notify and notifyall, after one thread woken and acquired lock, is that all other thread waiting becomes busy wait?

  • @WhoAmI True, in this context, it's probably the same thing... – MadProgrammer May 13 '14 at 05:28
  • You are calling `sleep` within the `synchronized` block, until you exit the `synchronized` block, no other threads who are also `synchronized` on the same monitor lock can do anything. – MadProgrammer May 13 '14 at 05:29
  • exactly what happens after the notify? thread under sleep will be waken up and it realizes that it can't acquire the lock, what happens then? Does it goes for wait again, 1, if yes, there is no notify to wake up again. 2, if no, it should be busy wait. please clarify. – user3631009 May 13 '14 at 05:52
  • 1
    Until the code exits the `synchornized` block, any thread in a `wait` state will continue to "wait" until the monitor lock is released at which time (a random waiting) thread will awaken – MadProgrammer May 13 '14 at 06:02
  • 1
    @user3631009: It seems you don’t know what “busy wait” means but just like to write that term all the time when you actually mean just “wait”. Just remove the word “busy” from your question and statements and they start making sense. – Holger May 13 '14 at 08:48
  • The conditions under which it is safe to use notify() instead of notifyAll() are laid out in Java Concurrency in Practice, 14.2.4 (http://amzn.to/1jyE5Kx) – Brian Goetz May 30 '14 at 18:46

3 Answers3

2

wait() doesn't busy-wait, but it does "compete in the usual manner with other threads for the right to synchronize on the object" once notified.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • exactly what happens after the notify? thread under sleep will be waken up and it realizes that it can't acquire the lock, what happens then? Does it goes for wait again, 1, if yes, there is no notify to wake up again. 2, if no, it should be busy wait. please clarify. – user3631009 May 13 '14 at 05:53
  • 1
    There is a 'thundering herd' of threads that all run trying to claim the lock. One of them wins, the rest of them go back to waiting. – user207421 May 13 '14 at 09:57
1

A call to notify wakes up one thread that is currently waiting on the object's condition queue which then tries to reaquire the lock which is still held by the calling thread at that point of time. So the situation is comparable to a thread that wants to enter a synchronized block that is currently executed by another thread. The thread is not doing a busy-wait, it is just blocked until it can aquire the lock.

When the thread that called notify releases its lock, the other thread can be unblocked and continue to work.

The same is true for notifyAll, but it wakes up all threads that are waiting on the object's condition queue. As only one of them can acquire the lock, the others stay blocked until they get the lock - one after the other. This and because thread-awaking signals may happen spontaneous it is required to always call wait within a conditional loop:

synchronized (lockObject) {
    // ...
    while (!condition) {
        lockObject.wait();
    }
    // object is now in desired state
}

See also: Java Concurrency in Practice, Chapter 14.2

isnot2bad
  • 24,105
  • 2
  • 29
  • 50
0

A thread can wait on an object only when IT OWNS the object's monitor. Once the first thread notifies, the second thread wakes up but doesn't do anything. The only thing that happens here is that "The thread will be removed from the list of threads waiting on the object . It is left to the OS to schedule its execution. The OS might choose NOT to execute it for sometime. The thread doesn't busy-wait. It will just be in the set of threads which are waiting to be scheduled.

As @Holger points out, any thread which calls wait() releases the lock on the object. Once it is notified, it has to "compete" and reacquire the lock on the object. Reacquiring of lock doesn't happen when notify() is called by the thread which holds the lock. It happens when that thread exits its synchronized block.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • 1
    You missed the point that a thread calling `wait` *releases* the monitor as otherwise no other thread could ever call `notify`. Therefore it has to reacquire the monitor which it can only after the thread which called `notify` has left its `synchronized` block. That’s the prerequisite of this question. – Holger May 13 '14 at 08:44