【发布时间】:2019-01-20 08:47:51
【问题描述】:
我创建了一个用于研究目的的项目,该项目使用 Threads 模拟餐厅服务。有一个供厨师准备餐点的线程和另一个供服务员提供餐点的线程。当我用 1 名厨师和 5 名服务员对其进行测试时,效果很好。但是当我增加厨师的数量时,程序会无限期地运行。怎么了?代码如下:
类主
package restaurant;
import java.util.concurrent.Semaphore;
public class Main {
public static int MAX_NUM_MEALS = 5;
public static int OLDEST_MEAL = 0;
public static int NEWEST_MEAL = -1;
public static int DONE_MEALS = 0;
public static int NUM_OF_COOKS = 1;
public static int NUM_OF_WAITERS = 5;
public static Semaphore mutex = new Semaphore(1);
static Cook cookThreads[] = new Cook[NUM_OF_COOKS];
static Waiter waiterThreads[] = new Waiter[NUM_OF_WAITERS];
public static void main(String[] args) {
for(int i = 0; i < NUM_OF_COOKS; i++) {
cookThreads[i] = new Cook(i);
cookThreads[i].start();
}
for(int i = 0; i < NUM_OF_WAITERS; i++) {
waiterThreads[i] = new Waiter(i);
waiterThreads[i].start();
}
try {
for(int i = 0; i < NUM_OF_COOKS; i++) {
cookThreads[i].join();
}
for(int i = 0; i < NUM_OF_WAITERS; i++) {
waiterThreads[i].join();
}
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("All done");
}
}
类厨师
package restaurant;
public class Cook extends Thread{
private int id;
public Cook(int id) {
this.id = id;
}
public void run() {
while(true) {
System.out.println("Cook " + id + " is prepearing meal");
try {
Thread.sleep(1000);
Main.mutex.acquire();
Main.NEWEST_MEAL++;
Main.mutex.release();
Main.mutex.acquire();
Main.DONE_MEALS++;
Main.mutex.release();
System.out.println("Cook " + id + " has finished the meal");
if(Main.DONE_MEALS == 5) {
System.out.println("Cook " + id + " has finished his job");
break;
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
班级服务员
package restaurant;
public class Waiter extends Thread{
private int id;
public Waiter(int id) {
this.id = id;
}
public void run() {
while(true) {
System.out.println("Waiter " + id + " will check if there is any meal to serve");
if(Main.NEWEST_MEAL >= Main.OLDEST_MEAL) {
try {
Main.mutex.acquire();
Main.OLDEST_MEAL++;
Main.mutex.release();
System.out.println("Waiter " + id + " is picking up meal");
Thread.sleep(500);
System.out.println("Waiter " + id + " has delivered the meal to client");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(Main.DONE_MEALS == 5) {
System.out.println("Waiter " + id + " has finished his job");
break;
}
System.out.println("No meal to serve. Waiter " + id + " will come back later");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
【问题讨论】:
-
考虑如果 6 个或更多厨师增加了
DONE_MEALS会发生什么,以及这如何影响您的停止条件if(Main.DONE_MEALS == 5)...
标签: java multithreading