这是我之前提出的问题 here 的后续问题.
我现在正在使用 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);
}
}
}
我的代码只在第一次工作(第一次生产和第一次消费),但第二次就不行了。我猜等待/通知逻辑在某处失败了。生产者将新作业推送到队列中,但消费者不再查看
任何项目。事实上,它甚至没有进入 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
s 它。参见 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html#take()供引用。
对于 InterruptedException
,您可能想在这里查看:Handling InterruptedException in Java
编辑:添加了缺失的 try{} catch()
关于java - 具有等待/通知的生产者消费者代码不适用于第二个产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53823767/