我的代码如下所示,它有两个Runnable类:Cook(生产者)和Waiter(消费者)。
当饭菜数少于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();
}
}
答案 0 :(得分:2)
首先,exec.shutdown()
仅表示执行者不接受新任务。如果您要取消现有任务,则需要致电exec.shutdownNow()
。
其次,捕获InterruptedException
会重置线程的中断标记,而while(!Thread.interrupted())
将无法按预期工作。
最后,即使你在捕获异常后用Thread.currentThread().interrupt()
重置了中断的标志,各种条件(例如while (mealList.size() < 5)
)可能仍然是假的,你将永远循环而不会到达你所在的行检查是否中断。