简体   繁体   English

具有wait / notify的生产者消费者代码在第二次生产时不起作用

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

This is a follow-up question from my previous question asked here . 这是我刚才的问题问一个跟进的问题在这里

I am using a PriorityBlockingQueue now. 我现在正在使用PriorityBlockingQueue I changed my producer to the following: 我将生产者改为以下内容:

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

And changed Consumer to the following. 并将Consumer改为以下内容。 Full code skeleton is here: 完整的代码框架在这里:

//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);
}
}
}

My code only works for the first time (first produce and first consume), but it doesn't work for the second time. 我的代码只适用于第一次(第一次生产和第一次消费),但它第二次不起作用。 Somewhere the wait/notify logic fails I guess. 在某个地方,我猜想等待/通知逻辑失败了。 The producer pushes new jobs to the queue, but the consumer doesn't peek any more items. 生产者将新作业推送到队列,但消费者不再peek任何项目。 In fact, it doesn't even go to the while loop and no more 111111111111111 printing. 事实上,它甚至没有进入while循环而且没有更多的111111111111111打印。

What is the problem? 问题是什么? How to fix it? 怎么解决?

You could simplify all this code to just: 您可以将所有这些代码简化为:

In the Producer: 在制作人:

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

and in the Consumer: 在消费者中:

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

When using an PriorityBlockingQueue , you don't need any syncronized statements, since they're inside the PriorityBlockingQueue already. 使用PriorityBlockingQueue ,您不需要任何syncronized语句,因为它们已经在PriorityBlockingQueue And according to the documentation take() wait for an element to be added if necessary and than poll s it. 根据文档, take()等待一个元素在必要时添加,而不是poll它。 See https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html#take() for reference. 请参阅https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html#take()以供参考。

And for the InterruptedException you might want to take a look here: Handling InterruptedException in Java 对于InterruptedException您可能需要查看: 在Java中处理InterruptedException

Edit: added missing try{} catch() 编辑:添加缺少try{} catch()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM