My code is shown below, it has two Runnable class: Cook(producer) and Waiter(consumer).
Cook will go to work when the number of meal less than 5,
waiter will go to work when the number of meal more than 0.
It runs properly but cannot stop.
I put a exec.shutdown()
in the end of my code, but nothing happened.
If I replace it with exec.shutdownNow()
, it will throw 2 InterruptedException
when trying to sleep. After that, the program is still running.
How can I stop it?
Is my code a proper way to "simulate" the ProducerConsumer situation?(this is my first try on concurrency)
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();
}
}