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.
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.