Java notifyAll()没有自己的队列

时间:2015-01-18 13:09:09

标签: java thread-synchronization

以下是来自线程的代码块:

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

将会有许多消费者和制作人同时启动,所以为了简单起见我选择了输出作为序列号。

1 个答案:

答案 0 :(得分:1)

  

这是否意味着notifyAll()无法在将来的等待中工作,仅适用于等待的线程"现在"

是。 notifyAll()通知所有等待的线程。不是将来会等待锁定的线程。

一个线程等待锁定,因为它在某种情况下无法继续,直到某些条件得到验证。例如,消息发送线程无法继续,直到有可用的消息继续进行。退出等待状态时线程应该做的第一件事是再次检查条件。如果条件得到验证,则应继续。否则,它应该再等一下。

目前还不清楚你的意图是什么。如果你正在设计一个生产者/消费者系统,你应该共享一个数据结构(一个"生成的东西,必须消费的东西)。消费者应该等到生产者将一些东西放入清单中。

而这正是BlockingQueue为您所做的,而不会强迫您使用wait()和notifyAll()。你应该使用BlockingQueue,它提供了一个更容易使用,更高杠杆的抽象。