黑马程序员技术交流社区

标题: 等待唤醒机制---线程间通信普通版与优化版 [打印本页]

作者: 追逐    时间: 2014-3-18 19:56
标题: 等待唤醒机制---线程间通信普通版与优化版
本帖最后由 追逐 于 2014-3-21 19:36 编辑

1,普通版
/*
        线程间通信
        其实就是多个线程在操作同一个资源
        只是操作的动作不同
        
        
        
wait();
notify();
notifyAll();

都是用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程持有的锁
只有同一个锁上的被等待线程。可以被同一个锁上的notify唤醒
不可以对不同锁中的线程进行唤醒。

也就是说。等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中
        
*/
  1. //定义一个资源类
  2. class Person {
  3.         String name;
  4.         String sex;
  5.         boolean b = false; //定义一个标记
  6. }

  7. //定义一个输入类
  8. class Input implements Runnable {
  9.         
  10.         private Person p; //定义一个资源类的对象
  11.         Input(Person p) {
  12.                         this.p = p;
  13.         }
  14.         
  15.         //建立run方法
  16.         public void run() {
  17.                 int x = 0;
  18.                 while(true) {
  19.                         synchronized(p) { //因为线程出现安全隐患问题。所以加上同步
  20.                                 if(p.b)
  21.                                         //假如标记为真。就wait();进入等待状态
  22.                                         try {p.wait();} catch(InterruptedException e) {}
  23.                                 if(x == 0) {
  24.                                         p.name = "shasha";
  25.                                         p.sex = "girl";
  26.                                 } else {
  27.                                         p.name = "志志";
  28.                                         p.sex = "男";
  29.                                 }
  30.                                 x = (x + 1) % 2;
  31.                                 p.b = true; //把标记改为真。
  32.                                 p.notify(); //唤醒等待的程序
  33.                         }
  34.                 }
  35.         }
  36.         
  37. }

  38. //定义一个输出类
  39. class Output implements Runnable {
  40.         
  41.         private Person p;
  42.         Output(Person p) {
  43.                 this.p = p;
  44.         }
  45.         
  46.         public void run() {
  47.                 while(true) {
  48.                         synchronized(p) { //因为对象p是唯一的。所以把p定义为同步锁
  49.                                 if(!p.b)
  50.                                         try {p.wait();} catch(InterruptedException e) {}
  51.                                 System.out.println(p.name + "run ...." + p.sex);
  52.                                 p.b = false; //把标记改为假
  53.                                 p.notify(); //唤醒等待的线程
  54.                         }
  55.                 }
  56.         }
  57.         
  58. }

  59. //定义一个调试类
  60. class InputOutputDemo {
  61.         public static void main(String[] args) {
  62.                 Person p = new Person(); //建立资源类
  63.                 Input in = new Input(p); //把资源类对象当做实参传递给输入类的构造函数
  64.                 Output ou = new Output(p); //把资源类对象当做实参传递给输出类的构造函数
  65.                 Thread t1 = new Thread(in);
  66.                 Thread t2 = new Thread(ou);
  67.                 t1.start();
  68.                 t2.start();
  69.         }
  70. }




  71. 2,优化后的代码(优化版)
  72. //定义一个资源类
  73. class Person1 {
  74.         private String name;
  75.         private String sex;
  76.         boolean b = false; //定义一个标记
  77.         //在资源类中定义一个赋值函数,但是有可能在赋值的时候出现问题。所以使用同步,变成同步函数
  78.         public synchronized void set(String name, String sex) {
  79.                 if(b)
  80.                         //假如标记为真。就wait();进入等待状态
  81.                         try {this.wait();} catch(InterruptedException e) {}
  82.                 this.name = name;
  83.                 this.sex = sex;
  84.                 this.b = true;
  85.                 this.notify();
  86.         }
  87.         
  88.         public synchronized void out() {
  89.                 if(!b)
  90.                         try {this.wait();} catch(InterruptedException e) {}
  91.                 System.out.println(name + "run......" + sex);
  92.                 this.b = false;
  93.                 this.notify();
  94.         }
  95.         
  96. }

  97. //定义一个输入类
  98. class Input1 implements Runnable {
  99.         
  100.         private Person1 p; //定义一个资源类的对象
  101.         Input1(Person1 p) {
  102.                         this.p = p;
  103.         }
  104.         
  105.         //建立run方法
  106.         public void run() {
  107.                 int x = 0;
  108.                 while(true) {
  109.                         if(x == 0) {
  110.                                 p.set("meimei", "girl");
  111.                         } else {
  112.                                 p.set("志志", "男");
  113.                         }
  114.                         x = (x + 1) % 2;
  115.                 }
  116.         }
  117.         
  118. }

  119. //定义一个输出类
  120. class Output1 implements Runnable {
  121.         
  122.         private Person1 p;
  123.         Output1(Person1 p) {
  124.                 this.p = p;
  125.         }
  126.         
  127.         public void run() {
  128.                 while(true) {
  129.                         p.out();
  130.                 }
  131.         }
  132.         
  133. }

  134. //定义一个调试类
  135. class InputOutputDemo1 {
  136.         public static void main(String[] args) {
  137.                 Person1 p = new Person1();
  138.                 new Thread(new Input1(p)).start();
  139.                 new Thread(new Output1(p)).start();
  140.         }
  141. }
复制代码







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2