[英]How to stop Java Threads in a ProducerConsumer situation?
我的代码如下所示,它具有两个Runnable类:Cook(producer)和Waiter(consumer)。
做饭的时候用餐次数少于5次
用餐人数超过0时服务员将上班。
它可以正常运行,但无法停止。
我在代码末尾放置了exec.shutdown()
,但是什么也没发生。
如果我将其替换为exec.shutdownNow()
,则在尝试睡眠时它将抛出2 InterruptedException
。 之后,程序仍在运行。
我该如何阻止它?
我的代码是“模拟” ProducerConsumer情况的正确方法吗?(这是我第一次尝试并发)
package com.imooc;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class Meal {
private final int id;
Meal(int id) {
this.id = id;
}
public String toString() {
return "Meal: " + id;
}
}
class Cook implements Runnable {
private LinkedList<Meal> mealList;
private static int count;
Cook(LinkedList<Meal> mealList) {
this.mealList = mealList;
}
public void run() {
while (!Thread.interrupted()) {
synchronized (mealList) {
while (mealList.size() < 5) {
System.out.print("Cook is cooking meal:");
System.out.println(++count);
mealList.add(new Meal(count));
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mealList.notifyAll();
while (mealList.size() == 5) {
System.out.println("Cook is waiting");
try {
mealList.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
System.out.println("Cook is off-duty");
}
}
class Waiter implements Runnable {
private LinkedList<Meal> mealList;
Waiter(LinkedList<Meal> mealList) {
this.mealList = mealList;
}
public void run() {
while (!Thread.interrupted()) {
synchronized (mealList) {
while (mealList.size() > 0) {
System.out.println("Waiter is taking this meal:" + mealList.getLast());
mealList.removeLast();
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mealList.notifyAll();
while (mealList.size() == 0) {
System.out.println("Waiter is waiting");
try {
mealList.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
System.out.println("Waiter is off-duty");
}
}
public class Manager {
public static void main(String args[]) {
LinkedList<Meal> mealList = new LinkedList<Meal>();
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Waiter(mealList));
exec.execute(new Cook(mealList));
exec.execute(new Waiter(mealList));
exec.execute(new Waiter(mealList));
exec.execute(new Cook(mealList));
exec.shutdown();
}
}
首先, exec.shutdown()
仅意味着执行者将不接受新任务。 如果要取消现有任务,则需要调用exec.shutdownNow()
。
其次,捕获InterruptedException
重置线程的中断标志,并且while(!Thread.interrupted())
将无法按预期工作。
最后,即使您在捕获到异常之后使用Thread.currentThread().interrupt()
重置了中断标志,各种while条件(例如, while (mealList.size() < 5)
仍然可能为假,并且您将永远循环而不到达检查中断的那条线。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.