java - 具有等待/通知的生产者消费者代码不适用于第二个产品

标签 java multithreading queue producer-consumer notify

这是我之前提出的问题 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/

相关文章:

c - 使用 BFS 计算源和顶点之间的距离

java - 阻塞队列和 InterruptedException

java - 为什么 Android Studio 自动导入内联类而不是在我的代码顶部?

java - Java 中的这个 log10(int) 方法到底是做什么的?

Java 并发数 : how to retrieve data from several thousands TCP sockets at once and synchronously?

java - 如何同步一组线程?

java - 如何配置 Apache 将子域重定向到 Tomcat 应用程序

java - 尝试将 BLOB 作为 InputStream 读取,但出现连接关闭错误。 Spring3 getJdbcTemplate() 方法

python - 在 python 中稍后杀死线程

java - java中哪个线程安全队列效率更高