wait/notify 的生产者消费者代码不适用于第二个产品

Producer consumer code with wait/notify doesn't work on second produce

这是我之前提出的问题 的后续问题。

我现在正在使用 PriorityBlockingQueue。我将制作人更改为以下内容:

synchronized(Manager.queue) {
    Manager.queue.add(new Job());
    Manager.queue.notify();
}

并将Consumer更改为以下内容。完整的代码框架在这里:

//my consumer thread run()
public void run() {
synchronized(Manager.queue) {
    while (Manager.queue.peek() == null) {
                System.out.println("111111111111111");
                try {
                    Manager.queue.wait();
                } catch (InterruptedException e) {
                }
            }
    Job job=Manager.queue.peek();
if (job != null) {
                submitJob(job);
                if (job.SubmissionFailed.equals("false")) {
                    // successful submission. Remove from queue. Add to another.
                    Manager.queue.poll();
                    Manager.submissionQueue.put(job.uniqueid, job);
}
}
}

我的代码只在第一次有效(第一次生产和第一次消费),但第二次无效。我猜 wait/notify 逻辑在某处失败了。生产者将新作业推送到队列中,但消费者不再 peek 任何项目。事实上,它甚至没有进入 while 循环,也没有更多的 111111111111111 打印。

有什么问题?如何解决?

您可以将所有这些代码简化为:

在制作人中:

Manager.queue.add(new Job());

在消费者中:

while (true) {
    try {
        submitJob(Manager.queue.take()); //or do something else with the Job
        //your code here, then remove the break
        break;
    } catch (InterruptedException ex) {
        //usually no need to do anything, simply live on unless you
        //caused that
    }
}
//or your code here, then you need an surrounding while and the break

使用 PriorityBlockingQueue 时,您不需要任何 syncronized 语句,因为它们已经在 PriorityBlockingQueue 中。并且根据文档 take() 等待添加元素(如有必要),然后 poll 添加它。请参阅 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html#take() 以供参考。

对于 InterruptedException 你可能想看看这里:Handling InterruptedException in Java

编辑:添加缺失的 try{} catch()