具有wait / notify的生产者消费者代码在第二次生产时不起作用 [英] Producer consumer code with wait/notify doesn't work on second produce

查看:235
本文介绍了具有wait / notify的生产者消费者代码在第二次生产时不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is a follow-up question from my previous question asked here.

我现在正在使用 PriorityBlockingQueue 。我将生产者更改为以下内容:

I am using a PriorityBlockingQueue now. I changed my producer to the following:

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

并更改消费者以下。完整的代码框架在这里:

And changed Consumer to the following. 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);
}
}
}

我的代码仅适用于第一次(第一次产生和第一次消费),但它第二次不起作用。在某个地方,等待/通知逻辑失败了。生产者将新作业推送到队列,但消费者不再偷看更多项目。事实上,它甚至没有转到循环,而且 111111111111111 打印不再。

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. In fact, it doesn't even go to the while loop and no more 111111111111111 printing.

有什么问题?如何解决?

What is the problem? How to fix it?

推荐答案

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

You could simplify all this code to just:

在制片人:

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 ,您不需要任何同步语句,因为它们位于 PriorityBlockingQueue 已经。并根据文档 take()等待必要时添加元素,而不是 poll s。请参阅 https:// docs .oracle.com / javase / 7 / docs / api / java / util / concurrent / PriorityBlockingQueue.html#take()供参考。

When using an PriorityBlockingQueue, you don't need any syncronized statements, since they're inside the PriorityBlockingQueue already. And according to the documentation take() wait for an element to be added if necessary and than polls it. See https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html#take() for reference.

您可能需要查看 InterruptedException 处理Java中的InterruptedException

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

这篇关于具有wait / notify的生产者消费者代码在第二次生产时不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆