线程间的通信 设置线程等待与线程唤醒

                                                  

代码实现上述框图:

  1 //等待唤醒机制
  2 
  3 /*
  4 wait(),notify(),notifyAll()必须用在同步中,因为同步中才有锁。
  5 指明让持有那个锁的线程去等待或被唤醒,例如object.wait(),表明让持有object这把锁的线程等待。
  6 
  7 wait():让线程进入等待状态,就是把线程放入了线程池。
  8 notify():唤醒线程池中的任意一个线程(持有特定锁的任意一个线程)。
  9 notifyAll():唤醒所有线程。
 10 
 11 wait(),notify(),notifyAll()为什么定义在Object中?
 12 锁可以是任意的对象,任意对象都可以调用的方法需要定义在Object中。
 13 */
 14 
 15 
 16 //描述数据
 17 class Resource 
 18 {
 19     public String name;
 20     public String gender;
 21     public boolean flag;             //添加标记,默认为false;标志位的用途:例如:Input存完一组数据可能继续持有CPU,存完后将flag置反,则Input无法继续存入数据。
 22     public Resource(){}
 23 }
 24 
 25 //描述输入任务
 26 class Input implements Runnable
 27 {
 28     private Resource res;
 29     public Input(Resource res)
 30     {
 31         this.res = res;
 32     }
 33     public void run()
 34     {
 35         int i = 1;
 36         while(true)
 37         {
 38             synchronized(res)       //加同步锁①
 39             {
 40                 if(res.flag)
 41                 {    
 42                     //等待的线程会放弃锁,跟sleep不同,sleep的线程仍然拥有锁。
 43                     try{res.wait();}catch(InterruptedException e){e.printStackTrace();}        //判断flag标志,先判断该不该存,如果为true,放弃CPU。
 44                 }
 45                 if(i==1)
 46                 {
 47                     res.name = "猪小明";
 48                     res.gender = "男";
 49                 }
 50                 else
 51                 {
 52                     res.name = "腿腿";
 53                     res.gender = "女";
 54                 }
 55                 i=(++i)%2;               //0、1切换
 56                 res.flag = true;
 57                 res.notify();            //唤醒对方,允许空唤醒。
 58                 //try{res.wait();}catch(InterruptedException e){e.printStackTrace();}
 59             }
 60         }
 61     }
 62 }
 63 
 64 //描述输出任务
 65 class Output implements Runnable
 66 {
 67     private Resource res;
 68     public Output(Resource res)
 69     {
 70         this.res = res;
 71     }
 72     public void run()
 73     {
 74         while(true)
 75         {    
 76             synchronized(res)      //加同步锁②,①处和此处为同一把锁!
 77             {
 78                 if(!res.flag)
 79                 {
 80                     try{res.wait();}catch(InterruptedException e){e.printStackTrace();}        //判断flag标志,先判断该不该存,如果为false,放弃CPU。
 81                 }
 82                 System.out.println(res.name + "....." + res.gender);
 83                 res.flag = false;
 84                 res.notify();          //唤醒对方
 85                 //try{res.wait();}catch(InterruptedException e){e.printStackTrace();}
 86             }
 87         }
 88     }
 89 }
 90 
 91 class TestDengdai
 92 {
 93     public static void main(String[] args)
 94     {
 95         //创建资源
 96         Resource res = new    Resource();
 97         //创建输入任务
 98         Input input = new Input(res);
 99         //创建输出任务
100         Output output = new Output(res);
101         //创建输入线程
102         Thread t1 = new Thread(input);
103         //创建输出线程
104         Thread t2 = new Thread(output);
105         //启动线程
106         t1.start();
107         t2.start();
108 
109     }
110 }

 

 

 

 

上述代码实现存入一个输出一个的运行效果:

posted @ 2016-11-07 21:20  ninan_ton  阅读(190)  评论(0)    收藏  举报