线程间通讯:
其实就是多个线程在操作同一个资源,
就是操作的动作不同
1 class Res 2 { 3 String name; 4 String sex; 5 } 6 7 class Input implements Runnable 8 { 9 private Res r; 10 Object obj = new Object(); 11 Input(Res r) 12 { 13 this.r = r; 14 } 15 public void run() 16 { 17 int x = 0; 18 while(true) 19 { 20 synchronized(obj) 21 { 22 if(x==0) 23 { 24 r.name = "mike"; 25 r.sex = "man"; 26 } 27 else 28 { 29 r.name = "LILY"; 30 r.sex = "LADY"; 31 } 32 } 33 x = (x+1)%2; 34 } 35 } 36 } 37 38 class Output implements Runnable 39 { 40 private Res r; 41 Object obj = new Object(); 42 Output(Res r) 43 { 44 this.r = r; 45 } 46 public void run() 47 { 48 while(true) 49 { 50 synchronized(obj) 51 { 52 System.out.println(r.name+"..."+r.sex); 53 } 54 } 55 } 56 } 57 58 class InputOutputDemo 59 { 60 public static void main(String[] args) 61 { 62 Res r = new Res(); 63 64 Input in = new Input(r); 65 Output out = new Output(r); 66 67 Thread t1 = new Thread(in); 68 Thread t2 = new Thread(out); 69 70 t1.start(); 71 t2.start(); 72 } 73 }
wait()
notify()
notifyAll()
都使用在同步中,因为要对持有监视器(锁)的线程操作
所以要使用在同步中,因为只有同步才具有锁的概念
为什么这些操作线程的方法要定义在Object类中呢
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程所持有的锁
只有同一个锁上的被等待线程可以被同一个锁上的notify唤醒
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中
1 class Res 2 { 3 String name; 4 String sex; 5 boolean flag = false; 6 } 7 8 class Input implements Runnable 9 { 10 private Res r; 11 Input(Res r) 12 { 13 this.r = r; 14 } 15 public void run() 16 { 17 int x = 0; 18 while(true) 19 { 20 synchronized(r) 21 { 22 if(r.flag) 23 try{r.wait();}catch(Exception e){} 24 if(x==0) 25 { 26 r.name = "mike"; 27 r.sex = "man"; 28 } 29 else 30 { 31 r.name = "LILY"; 32 r.sex = "LADY"; 33 } 34 x = (x+1)%2; /*转换性别*/ 35 r.flag = true; 36 r.notify(); 37 } 38 } 39 } 40 } 41 42 class Output implements Runnable 43 { 44 private Res r; 45 Output(Res r) 46 { 47 this.r = r; 48 } 49 public void run() 50 { 51 while(true) 52 { 53 synchronized(r) 54 { 55 if(!r.flag) 56 try{r.wait();}catch(Exception e){} 57 System.out.println(r.name+"..."+r.sex); 58 r.flag = false; 59 r.notify(); 60 } 61 } 62 } 63 } 64 65 class InputOutputDemo 66 { 67 public static void main(String[] args) 68 { 69 Res r = new Res(); 70 71 Input in = new Input(r); 72 Output out = new Output(r); 73 74 Thread t1 = new Thread(in); 75 Thread t2 = new Thread(out); 76 77 t1.start(); 78 t2.start(); 79 } 80 }
优化
1 class Res 2 { 3 private String name; 4 private String sex; 5 private boolean flag = false; 6 7 public synchronized void set(String name,String sex) 8 { 9 if(flag) 10 try{this.wait();}catch(Exception e){} 11 this.name = name; 12 this.sex = sex; 13 14 flag = true; 15 this.notify(); 16 } 17 public synchronized void out() 18 { 19 if(!flag) 20 try{this.wait();}catch(Exception e){} 21 System.out.println(name+"..."+sex); 22 flag = false; 23 this.notify(); 24 } 25 } 26 27 class Input implements Runnable 28 { 29 private Res r; 30 Input(Res r) 31 { 32 this.r = r; 33 } 34 public void run() 35 { 36 int x = 0; 37 while(true) 38 { 39 if(x==0) 40 { 41 r.set("mike","man"); 42 } 43 else 44 { 45 r.set("LILY","LADY"); 46 } 47 x = (x+1)%2; /*转换性别*/ 48 } 49 } 50 } 51 52 class Output implements Runnable 53 { 54 private Res r; 55 Output(Res r) 56 { 57 this.r = r; 58 } 59 public void run() 60 { 61 while(true) 62 { 63 r.out(); 64 } 65 } 66 } 67 68 class InputOutputDemo 69 { 70 public static void main(String[] args) 71 { 72 Res r = new Res(); 73 74 Input in = new Input(r); 75 Output out = new Output(r); 76 77 Thread t1 = new Thread(in); 78 Thread t2 = new Thread(out); 79 80 t1.start(); 81 t2.start(); 82 } 83 }