我正在对多线程进行一些研究并尝试编写程序。
我编写了一个餐厅程序,模拟并行服务多个客户:
- 一家餐厅开张,创建一个服务员、一个厨师、一些顾客,然后等到所有顾客都吃完饭
- 客户下订单,并等待他的布尔“吃”变为真,然后通知餐厅
- 服务员等待客户点菜,然后通知厨师
- 厨师等待服务员通知他订单,准备餐点并将客户的“已吃”设置为真
不知何故,我的程序将以大致不同的结果终止。
在我完成研究之后,我可以看到 2 个不同终止的原因:1)如果我的方法不同步(在我的程序中不是这种情况)。2)因为我们不能影响线程资源的分配方式,但是这会导致线程顺序的一些细微差别
但是我的程序以很大的差异终止,而不仅仅是线程序列的微小差异:
- 如果只有一个客户,它总是正确终止
- 如果有多个顾客,有时一切正常,餐厅关门。但有时它会在服务员第二次通知后卡住,此时厨师应该收到下一个订单。它不会终止,线程正在运行,但厨师只是不处理下一个订单。
有人可以给我任何提示吗?
厨师代码:
class Chef extends Thread{
private static int _id=1;
private int id;
Order order;
public Chef(){
this.id=_id;
_id++;
order=null;
this.start();
}
@Override
public void run() {
System.out.println("Chef ("+id+") starts to work...");
synchronized(this){
while(order==null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("Chef ("+id+") prepared Order ("+this.order.getId()+")");
Restaurant.customers.get(this.order.getId()-1).served=true;
synchronized(Restaurant.customers.get(this.order.getId()-1)){
Restaurant.customers.get(this.order.getId()-1).notify();
}
order=null;
}
public void prepareOrder(Order order){
this.order=order;
System.out.println("Chef ("+this.id+") prepares order ("+order.getId()+")");
synchronized(this){
this.notify();
}
}
}
服务员的代码(正常工作,总是处理传入的订单):
class Waiter extends Thread{
private static int _id=1;
private int id;
Order order;
public Waiter(){
this.id=_id;
_id++;
order=null;
this.start();
}
@Override
public void run() {
System.out.println("Waiter ("+this.id+") starts to work...");
synchronized(this){
while(takenOrder==false){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
order=null;
Restaurant.chefs.get(0).prepareOrder(order);
}
public void takeOrder(Order order){
this.order=order;
System.out.println("Waiter ("+this.id+") takes order ("+this.order.getId()+")");
synchronized(this){
this.notify();
}
}
}