厨师,顾客,订餐的多线程示例程序
1)wait方法要在一个循环中
public void waitForChef() throws InterruptedException {
while (readyFlag)
wait();
}
2)由于厨师线程有多个,顾客有多个,所以要用notifyAll方法,而不是notify,因为notify很容易就产生死锁
3)TimeUnit.MILLISECONDS.sleep(200); 用于降低程序的运行速度,用于示例
4)
while (!Thread.interrupted()) { <span style="font-family: Arial, Helvetica, sans-serif;">}</span>
用于检测异常,异常可能发生在sleep()方法中,也可能发生在wait方法中,也可能在while体中的其他部分,这时候下次执行while便会退出while循环,
由于
Thread.interrupted()
方法会清楚异常标识,所以最后
exec.shutdownNow();
执行时,有一部分线程的catch语句中的print语句并不会得到执行
5)条件检测和线程的主要任务执行都要放在synchronized块中
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class Meal {
private static int count=0;
private final int orderNum=++count ;
public String toString() {
return " Meal "+orderNum;
}
}
class WaitPerson implements Runnable {
private Restaurant restaurant;
public WaitPerson( Restaurant restaurant) {
this.restaurant=restaurant;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized(restaurant) {
restaurant.waitForEating();
System.out.println("The WaitPerson "+Thread.currentThread().getId()+" has eaten " + restaurant.meal);
restaurant.setReadyFlag(false);
restaurant.notifyAll();
}
}
} catch(InterruptedException e) {
System.out.print("Exiting via interrupt in WaitPerson in thread-->"
+ Thread.currentThread().getId());
}
System.out.print("Exiting in WaitPerson in thread-->"
+ Thread.currentThread().getId());
}
}
class Chef implements Runnable {
private Restaurant restaurant;
public Chef( Restaurant restaurant) {
this.restaurant=restaurant;
}
public void run() {
try {
while (!Thread.interrupted()) {
synchronized(restaurant) {
TimeUnit.MILLISECONDS.sleep(200);
restaurant.waitForChef();
restaurant.meal=new Meal();
System.out.println("The Chef "+Thread.currentThread().getId()+" has made" + restaurant.meal);
restaurant.setReadyFlag(true);
restaurant.notifyAll();
}
}
} catch(InterruptedException e) {
System.out.print("Exiting via interrupt in Chef in thread-->"
+ Thread.currentThread().getId());
}
System.out.print("Exiting in Chef in thread-->"
+ Thread.currentThread().getId());
}
}
public class Restaurant {
private boolean readyFlag=false; //true 做好了, false代表没做好
public Meal meal=null;
public void setReadyFlag(boolean readyFlag) {
this.readyFlag = readyFlag;
}
public void waitForChef() throws InterruptedException {
while (readyFlag)
wait();
}
public void waitForEating() throws InterruptedException {
while (readyFlag == false)
wait();
}
public static void main(String[] args) throws Exception {
Restaurant restaurant=new Restaurant();
ExecutorService exec = Executors.newFixedThreadPool(20);
for (int i = 0; i < 10; i++) {
exec.execute(new Chef(restaurant));
exec.execute(new WaitPerson(restaurant));
}
TimeUnit.SECONDS.sleep(10); // Run for a while...
exec.shutdownNow(); // Interrupt all tasks
}
}