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()
这是我之前提出的问题
我现在正在使用 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()