线程之间,通过wait() notify() notifyAll()来协作编程;
1. 必须在synchronized方法或方法块中使用
2. 与Thread.sleep()的区别:wait()方法释放持有的对象的锁。
3. 属于Object类的方法
4. 替代类:java.util.concurrent.locks.Condition 接口
5. 经典举例,生产者/消费者:餐馆有一个厨师负责生产食物,一个服务员负责上菜(消费食物);服务员必须在厨师生产完食物后工作,未生产完成时等待;系统必须有序的停止。
a)食物类:
class Meal {
private final int orderNum;
public Meal(int orderNum) {
this.orderNum = orderNum;
}
@Override
public String toString() {
return "Meal : " + orderNum;
}
}
b)厨师:
class Chef implements Runnable {
private Restaurant res;
private int count = 0;
public Chef(Restaurant res) {
this.res = res;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
synchronized (this) {
if(null != res.getMeal()) {
wait();
}
}
if(++count > 10) {
System.out.println("Out of food, close! ");
res.getExec().shutdownNow(); //通知wait收工
throw(new InterruptedException()); //自己收工
}
System.out.print("Order up! ");
synchronized (res.getWaitPerson()) {
res.setMeal(new Meal(count));
res.getWaitPerson().notifyAll();
}
TimeUnit.MICROSECONDS.sleep(100);
}
} catch(InterruptedException e) {
System.out.println("Chef interrupted! ");
}
}
}c)服务员:
class WaitPerson implements Runnable {
private Restaurant res;
public WaitPerson(Restaurant res) {
this.res = res;
}
@Override
public void run() {
try {
while(!Thread.interrupted()) {
synchronized (this) {
if(null == res.getMeal()) {
wait();
}
}
System.out.println("WaitPerson got " + res.getMeal());
synchronized (res.getChef()) {
res.setMeal(null); //上酸菜
res.getChef().notifyAll(); //通知厨师准备下一份
}
}
} catch(InterruptedException e) {
System.out.println("WaitPerson interrupted! ");
}
}
}d)餐馆:
public class Restaurant {
private Meal meal;
private Chef chef = new Chef(this);
private WaitPerson waitPerson = new WaitPerson(this);
private ExecutorService exec = Executors.newCachedThreadPool();
public Restaurant() {
exec.execute(chef);
exec.execute(waitPerson);
}
public Meal getMeal() {
return meal;
}
public void setMeal(Meal meal) {
this.meal = meal;
}
public Chef getChef() {
return chef;
}
public WaitPerson getWaitPerson() {
return waitPerson;
}
public ExecutorService getExec() {
return exec;
}
public static void main(String[] args) {
new Restaurant();
}
}//output Order up! WaitPerson got Meal : 1 Order up! WaitPerson got Meal : 2 Order up! WaitPerson got Meal : 3 Order up! WaitPerson got Meal : 4 Order up! WaitPerson got Meal : 5 Order up! WaitPerson got Meal : 6 Order up! WaitPerson got Meal : 7 Order up! WaitPerson got Meal : 8 Order up! WaitPerson got Meal : 9 Order up! WaitPerson got Meal : 10 Out of food, close! Chef interrupted! WaitPerson interrupted!
原文:http://blog.csdn.net/y172158950/article/details/21158291