线程间的通讯:
事实上就是多个线程在操作同一个资源。
可是操作动作不同
样例:
需求:模拟简单卖票系统(输入一个人。紧接着输出一个人)
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(); } }
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" >
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(); */ } }
时间: 2024-12-28 15:00:15