首页 > 学院 > 开发设计 > 正文

传统线程同步wait(),notify,notifyall()

2019-11-08 01:57:26
字体:
来源:转载
供稿:网友

java的Object类中有三个final的方法允许线程之间进行资源对象锁的通信,他们分别是: wait(), notify() ,notifyAll()。

调用这些方法的当前线程必须拥有此对象监视器,否则将会报java.lang.IllegalMonitorStateException exception异常。

wait

Object的wait方法有三个重载方法,其中一个方法wait() 是无限期(一直)等待,直到其它线程调用notify或notifyAll方法唤醒当前的线程;另外两个方法wait(long timeout) 和wait(long timeout, int nanos)允许传入 当前线程在被唤醒之前需要等待的时间,timeout为毫秒数,nanos为纳秒数。

notify

notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。

notifyAll

notifyAll 会唤醒所有等待(对象的)线程;

这些方法可以使用于“生产者-消费者”问题,消费者是在队列中等待对象的线程,生产者是在队列中释放对象并通知其他线程的线程。

例子:

public class TraditionalThreadCommunication {/*** @param args*/public static void main(String[] args) {final Business business = new Business();new Thread(new Runnable() {@Overridepublic void run() {for(int i=1;i<=20;i++){business.a(i);}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=1;i<=20;i++){business.b(i);}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for(int i=1;i<=20;i++){try {Thread.sleep(3000);} catch (InterruptedException e) {e.PRintStackTrace();}business.c(i);}}}).start(); }}  class Business { private boolean bShouldSub = true; public synchronized void a(int i){ System.out.println("a-start"+i); try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}  }  public synchronized void b(int i){ System.out.println("b-start"+i); try {this.wait();} catch (InterruptedException e) {e.printStackTrace();} }    public synchronized void c(int i){ System.out.println("c-start"+i); this.notifyAll(); }   }

c线程每执行一次休眠3秒唤醒所有等待的线程:

输出结果:

a-start1b-start1c-start1b-start2a-start2c-start2a-start3b-start3c-start3b-start4a-start4c-start4a-start5b-start5c-start5b-start6a-start6c-start6

............


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表