多线程间的通讯之等待唤醒机制

来源:互联网 发布:博拉网络上市最新消息 编辑:程序博客网 时间:2024/04/30 16:37

线程间的通讯:
其实就是多个线程在操作同一个资源。
但是操作动作不同

 

例子:

需求:模拟简单卖票系统(输入一个人,紧接着输出一个人)

 

class Res{String name;String sex;}class Input  implements Runnable{private Res r;private int t=0;Input(Res r){this.r=r;}public void run(){while(true){if(t==1){r.name="nike";r.sex="man";}else {r.name="丽丽";r.sex="女女";}t=(t+1)%2;}}}class Output  implements Runnable{private Res r;Output(Res r){this.r=r;}public void run(){while(true){System.out.println("output....."+r.name+"+++"+r.sex);}}}class InputOutputDemo{public static void main(String[] args){Res r=new Res();Input in=new Input(r);Output out=new Output(r);Thread t1=new Thread(in);Thread t2=new Thread(out);t1.start();t2.start();}}

出现了安全问题(输出了丽丽  MAN)

 

同步后

class Res{String name;String sex;}class Input  implements Runnable{private Res r;private int t=0;Input(Res r){this.r=r;}public void run(){while(true){synchronized(Res.class){if(t==1){r.name="nike";r.sex="man";}else {r.name="丽丽";r.sex="女女";}t=(t+1)%2;}}}}class Output  implements Runnable{private Res r;Output(Res r){this.r=r;}public void run(){while(true){synchronized(Res.class){System.out.println("output....."+r.name+"+++"+r.sex);}}}}class InputOutputDemo2{public static void main(String[] args){Res r=new Res();Input in=new Input(r);Output out=new Output(r);Thread t1=new Thread(in);Thread t2=new Thread(out);t1.start();t2.start();}}


虽然安全 问题解决了,但并没出现我们想要的一男一女交替的情景

 

 

这是就引进一种方法:等待唤醒机制

 

class Res{String name;String sex;boolean flag;}class Input  implements Runnable{private Res r;private int t=0;Input(Res r){this.r=r;}public void run(){while(true){synchronized(r){if(r.flag)try{r.wait();}catch(Exception e){}if(t==1){r.name="nike";r.sex="man";}else {r.name="丽丽";r.sex="女女";}t=(t+1)%2;r.flag=true;r.notify();}}}}class Output  implements Runnable{private Res r;Output(Res r){this.r=r;}public void run(){while(true){synchronized(r){if(!r.flag)try{r.wait();}catch(Exception e){}System.out.println("output....."+r.name+"+++"+r.sex);r.flag=false;r.notify();}}}}class InputOutputDemo3{public static void main(String[] args){Res r=new Res();Input in=new Input(r);Output out=new Output(r);Thread t1=new Thread(in);Thread t2=new Thread(out);t1.start();t2.start();}}

 


 

wait:
notify();
notifyAll();

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

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

也就是说,等待和唤醒必须是同一个锁。
而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。

 

 

下面进行代码改良:

class Res{private String name;private String sex;private boolean flag;public synchronized void  set(String name,String sex){if(this.flag)  try{this.wait();}catch(Exception e){}this.name=name;this.sex=sex;this.flag=true;  this.notify();}public synchronized void out(){if(!this.flag) try{this.wait();}catch(Exception e){}System.out.println("output....."+this.name+"+++"+this.sex);this.flag=false;this.notify();}}class Input  implements Runnable{private Res r;private int t=0;Input(Res r){this.r=r;}public void run(){while(true){synchronized(r){if(t==1)r.set("nike","man");else r.set("丽丽","女女女");t=(t+1)%2;}}}}class Output  implements Runnable{private Res r;Output(Res r){this.r=r;}public void run(){while(true){synchronized(r){r.out();}}}}class InputOutputDemo4{public static void main(String[] args){Res r=new Res();new Thread(new Input(r)).start();new Thread(new Output(r)).start();/*Input in=new Input(r);Output out=new Output(r);Thread t1=new Thread(in);Thread t2=new Thread(out);t1.start();t2.start();*/}}


 


 

 

 

 

0 0
原创粉丝点击