多线程并发中的简单使用wait和notify的方法

来源:互联网 发布:linux mysql 重启命令 编辑:程序博客网 时间:2024/06/05 14:29

package javautilconcurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 简单使用wait和notify
 * @author zly
 *
 */
public class UseWaitAndNotify {
 
 public static void main(String[] args) {
  ExecutorService service = Executors.newCachedThreadPool();
  Cup cup = new Cup("玻璃杯");
  // 开始时,杯子未洗干净,因此泡茶人被挂起  
  service.execute(new TeaMaker(cup));
  // 洗杯子的人发现杯子是不干净的,于是开始洗杯子,  
  // 洗完杯子后,通知泡茶的人,可以泡茶了  
  service.execute(new Washer(cup));
  service.shutdown();
 }
 
 /**
  * 列举一个洗杯子泡茶的流程
  *  1、先洗干净杯子,然后才能泡茶
  *  2、ok,茶泡好了,慢慢品尝一番,然后倒掉茶叶,准备重新泡一杯茶
  *  3、重复第一步和第二步
  */
 static class Cup{
  private volatile boolean washed = false;
  private String name;
  
  public Cup(){
   
  }
  
  public Cup(String name){
   this.name = name;
  }
  
  /**
   * 洗杯子操作
   */
  public synchronized void wash(Runnable owner) throws InterruptedException{
   System.out.println(owner.getClass().getSimpleName() + ">>正在洗杯子");
   Thread.sleep(3000);
   washed = true;
   //杯子洗干净后,可以泡茶了
   notifyAll();
   System.out.println(owner.getClass().getSimpleName() + ">>杯子洗干净了,你可以拿去泡茶用了");
  }
  
  /**
   * 泡茶操作
   */
  public synchronized void makeTea(Runnable owner) throws InterruptedException{
   System.out.println(owner.getClass().getSimpleName() + ">>准备泡茶");
   //如果杯子未被洗干净,那么我只有等待杯子被洗干净才能开始泡茶
   while(!washed){
    System.out.println(owner.getClass().getSimpleName()
      + ">>很无奈,杯子是脏的,我只有等它被洗干净,我自己懒得动手洗");
    wait();
   }
   System.out.println(owner.getClass().getSimpleName() +
     ">>终于拿到干净的杯子了,开始泡一杯茶");
  }
  
  public String toString(){
   return "Cup of " + this.name;
  }
 }
 
 /**
  * 清洁工线程
  */
 static class Washer implements Runnable{
  private Cup cup;
  
  public Washer(Cup cup){
   this.cup = cup;
  }
  
  public void run(){
   System.out.println(this.getClass().getSimpleName() + ">>我是清洁工,开始洗杯子");
   try {
    cup.wash(this);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }
 
 /**
  * 泡茶工线程
  */
 static class TeaMaker implements Runnable{
  private Cup cup;
  
  public TeaMaker(Cup cup){
   this.cup = cup;
  }
  
  public void run(){
   System.out.println(this.getClass().getSimpleName() + ">>我是泡茶工,我开始泡茶");
   try {
    cup.makeTea(this);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

}

输出结果为:

TeaMaker>>我是泡茶工,我开始泡茶
TeaMaker>>准备泡茶
TeaMaker>>很无奈,杯子是脏的,我只有等它被洗干净,我自己懒得动手洗
Washer>>我是清洁工,开始洗杯子
Washer>>正在洗杯子
Washer>>杯子洗干净了,你可以拿去泡茶用了
TeaMaker>>终于拿到干净的杯子了,开始泡一杯茶

或者:

TeaMaker>>我是泡茶工,我开始泡茶
Washer>>我是清洁工,开始洗杯子
TeaMaker>>准备泡茶
TeaMaker>>很无奈,杯子是脏的,我只有等它被洗干净,我自己懒得动手洗
Washer>>正在洗杯子
Washer>>杯子洗干净了,你可以拿去泡茶用了
TeaMaker>>终于拿到干净的杯子了,开始泡一杯茶