以下是来自线程的代码块:
synchronized(lock)
{
lock.notifyAll();
System.out.println("waking other threads up with lock:"+lock.hashCode());
}
这被称为四次,仍然无法唤醒其他线程。
具有此部分的其他线程:
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());
}
}
输出:
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
所以等待的线程无法唤醒。
这是否意味着notifyAll()无法在将来的等待中工作,仅适用于等待“现在”的线程(这意味着在cpu的相同周期或接近几个周期?)?如果是,如果我需要完全相同数量的等待唤醒,我是否需要添加一个变量以保存“通知”操作的数量?
我需要这种输出:
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
将会有许多消费者和制作人同时启动,所以为了简单起见我选择了输出作为序列号。
答案 0 :(得分:1)
这是否意味着notifyAll()无法在将来的等待中工作,仅适用于等待的线程"现在"
是。 notifyAll()通知所有等待的线程。不是将来会等待锁定的线程。
一个线程等待锁定,因为它在某种情况下无法继续,直到某些条件得到验证。例如,消息发送线程无法继续,直到有可用的消息继续进行。退出等待状态时线程应该做的第一件事是再次检查条件。如果条件得到验证,则应继续。否则,它应该再等一下。
目前还不清楚你的意图是什么。如果你正在设计一个生产者/消费者系统,你应该共享一个数据结构(一个"生成的东西,必须消费的东西)。消费者应该等到生产者将一些东西放入清单中。
而这正是BlockingQueue为您所做的,而不会强迫您使用wait()和notifyAll()。你应该使用BlockingQueue,它提供了一个更容易使用,更高杠杆的抽象。