2

What happens if you notify a lock, and immediately notify that lock again? Assume there are 2 or more threads waiting on that lock. Is it guaranteed that two threads are woken up? Or is it possible that only one threads is woken up, meaning that the second notification becomes obsolete?

lock.notify();
lock.notify();

Thanks!

Gray
  • 115,027
  • 24
  • 293
  • 354
Joape Maxe
  • 71
  • 6

2 Answers2

5

Assume there are 2 or more threads waiting on that lock. Is it guaranteed that two threads are woken up?

Yes. Each notify takes a thread from the waiting queue and puts it in the blocked queue -- the awoken thread must first get access to the synchronized lock in question. If there is only 1 thread waiting on the lock then the 2nd notify() would do nothing.

It is important to realize that the thread will not start executing immediately. Since it had to be in a synchronized block on lock to be able to do the wait() it must get access to the lock again before it can run. There may be multiple other threads already in the block queue, waiting to get access to lock.

Gray
  • 115,027
  • 24
  • 293
  • 354
  • First one wakes up and sleep again before second lock.notify is called - second thread won't be woken up? – djechlin Apr 03 '13 at 17:09
  • 1
    @Gray:`notify` is `native`.How can you be sure that this is the behavior?Why not for example the second `notify` does not do anything since a `notify` withing the current lock scope has already been raised? – Cratylus Apr 03 '13 at 17:10
  • Because that's not the Java spec @Cratylus. `Object.notify()` has a specification that has nothing to do with the native implementation. – Gray Apr 03 '13 at 17:12
  • @Gray:Yes but how do you know that the `notify` implementation "knows" that `notify` has already been called so it does not do anything? – Cratylus Apr 03 '13 at 17:13
  • The answer to your question @djechlin, is that it is implementation dependent. Most JVMs will put the first thread at the _end_ of the waiting queue so it would not get re-notified. But again, that is implementation specific. – Gray Apr 03 '13 at 17:13
  • The `notify()` call is a synchronous operation @Cratylus. It will make changes to thread states when it its called. The spec says that a call to `notify()` will wake up a blocked thread and that's what it does. – Gray Apr 03 '13 at 17:15
  • 1
    Of course @Cratylus, a JVM can be in violation of the spec but I have never used a JVM where 2 called to `notify()` would release less than 2 threads if they were waiting. – Gray Apr 03 '13 at 17:16
0

I suspect the behavior would be similar to calling notifyAll() (in this case it's more like a notifyTwo())

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.

Dwight DeGroff
  • 600
  • 3
  • 9
  • I think the OP is concerned with the case where the first thread to run preempts the caller, loops around to the wait again and so there are still two waiting threads when the next notify() is called. – Martin James Apr 03 '13 at 17:25