Java notifyAll() 本身没有队列

Java notifyAll() doesnt have a queue of itself

这是来自线程的代码块:

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() 不能对未来的等待起作用,而只对等待 "now" 的线程起作用(这意味着在 cpu 的同一周期或接近几个周期?)?如果是,如果我需要完全相同的等待唤醒次数,我是否需要添加一个变量来保存 "notify" 操作的数量?

我需要这种输出:

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

会有很多消费者和生产者同时启动,所以为了简单起见,我选择串行输出。

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

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

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

不清楚您的意图。如果您正在设计一个 producer/consumer 系统,您应该在线程之间共享一个数据结构(生成的 "things" 的列表,必须使用它)。消费者应等到生产者将内容放入列表中。

这正是 BlockingQueue 为您所做的,它不会强迫您搞乱 wait() 和 notifyAll()。您应该使用 BlockingQueue,它提供了更易于使用、更高级别的抽象。