0

Here is a code block from a thread:

synchronized(lock)
{
    lock.notifyAll();
    System.out.println("waking other threads up with lock:"+lock.hashCode());
}

This is called four times and still cannot wake other threads.

Other threads having this part:

synchronized(lock)
{
    while(continuing)
    {
        System.out.println("will wait on: "+lock.hashCode()); 
        try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}
        System.out.println("awaken on: "+lock.hashCode()); 
    }
}

Output:

 waking other threads up with lock: 68393799
 waking other threads up with lock: 68393799
 waking other threads up with lock: 68393799
 waking other threads up with lock: 68393799
 -- producer thread has finished so cannot revive consumers

 will wait on: 68393799
 -- stuck waiting forever itself, nothing to wake it up

so the waiting thread could not be awaken.

Does this mean notifyAll() cannot work on future waits and works only for threads waiting "now"(this means at the same cycle of cpu or close to several cycles?)? If yes, do I need to add a variable to save number of "notify" actions if I need exactly same number of wakings with waits?

I needed this kind of output:

wake up
wake up
wake up
wake up
---- producer thread finished its job here

---- consumer threads just began working from here
waiting thr0
awaken thr0

waiting thr1
waiting thr2

awaken thr2
awaken thr1

waiting thr3
awaken thr

there will be many consumers and producers started at the same time so I chose output as serial for simplicity.

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97

1 Answers1

1

Does this mean notifyAll() cannot work on future waits and works only for threads waiting "now"

Yes. notifyAll() notifies all the waiting threads. Not the threads that, in some future, will wait on the lock.

A thread waits on a lock because it's in a situation where it cann not proceed until some condition is verified. For example, a message sending thread can't proceed until there is a message available to proceed. The first thing a thread should do when exiting of its waiting state is to check the condition again. If the condition is verified, it should proceed. Otherwise, it should wait again.

It's unclear what your intention is. If you're designing a producer/consumer system, you should share a data structure (a list of "things" produced, that must be consumed) between threads. The consumer should wait until the producer has put something in the list.

And that's exactly what a BlockingQueue does for you, without forcing you to mess with wait() and notifyAll(). You should use a BlockingQueue, which provides a much easier to use, higher-lever abstraction.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thank you, I was using concurrent linked queue with poll() and offer() guarded by synchronization becuase they were not blocking. Should I try other methods of pop and push? – huseyin tugrul buyukisik Jan 18 '15 at 13:29
  • As the javadoc clearly indicates, the operations that are blocking are put() and take(). You don't need any synchronization to use a blocking queue, since those methods deal with synchronization for you. ConcurrentLinkedQueue is not a BlockingQueue. Look at BlockingQueue's javadoc to find all the implementations of this interface. – JB Nizet Jan 18 '15 at 13:32