Java线程 — 线程的通信 — wait方法和notify方法

线程通信:不同的线程执行不同的任务,如果这些任务有某种关系,线程之间必须能够通信,协调完成工作。

经典的生产者与消费者案例(Producer/Consumer)

分析案例:

  1.生产者和消费者应该操作共享的资源(实现方式来做)。

    2.使用一个或多个线程来表示生产者(Producer)。

    3.使用一个或多个线程来表示消费者(Consumer)。

为什么生产者不直接把数据给消费者,而是先把数据存储到共享资源中,然后消费者再从共享资源中获取再消费?

在这里体现了面向对象的设计理念:低耦合

  高(紧)耦合:直接使用生产者给消费者,那么生产者中得存在消费者引用,同理,消费者要消费生产者,消费者中也得存在生产者对象的引用。

    (松)耦合:使用一个中间对象,屏蔽了生产者和消费者直接的数据交互。

同步锁池:

  同步锁必须选则多个线程共同的资源对象。

  当前生产者在生产数据的时候(现拥有同步锁),其他线程就在锁池中待获取锁

  当线程执行完同步代码块的时候,就会释放同步锁,其他线程开始抢锁的使用权

线程通信wait方法和notify方法介绍:

java.lang.Object类提供类两类用于操作线程通信的方法。

wait():执行该方法的线程对象释放同步锁,JVM把该线程存放到等待池中等待其他的线程唤醒该线程

notify():执行该方法的线程唤醒在等待池中等待的任意一个线程,把线程转到锁池中等待。

notifyAll():执行该方法的线程唤醒在等待池中等待的所有线程。把线程转到锁池中等待。

注意:上述方法只能被同步监听锁对象来调用,否则报错IllegalMonitorStateException

----------------------------------------------------------------------------------------

多个线程只使用相同的一个对象的时候,多线程之间才有互斥效果。

我们把这个用来做互斥的对象称之为,同步监听锁对象/同步锁。

----------------------------------------------------------------------------------------

 同步锁对象可以选择任意类型的对象即可,只需要保证多个线程使用的是相同对象即可。

----------------------------------------------------------------------------------------

 因为,只有同步监听锁对象才能调用wait和notify方法,所以wait和notify方法应该存在于Object类中,而不是Thread类。

----------------------------------------------------------------------------------------

假设A线程和B线程共同操作一个X对象(同步锁),A,B线程可以通过X对象的wait和notify方法来进行通信,流程如下:

1.当A线程执行X对象的同步方法时,A线程持有X对象的锁,B线程没有执行机会,B线程在X对象的锁池中等待

2.A线程在同步方法中执行X.wait()方法时,A线程释放X对象的锁,进入A线程进入X对象的等待池中。

3.在X对象的锁池中等待的B线程获取X对象的锁,执行X的另一个同步方法。

4.B线程在同步方法中执行X.notify()方法时,JVM把A线程从X对象的等待池中移到X对象的锁池中,等待获取锁。

5.B线程执行同步方法,释放A线程获得锁,继续执行同步方法。

posted @ 2017-02-11 20:19  wenxudong  阅读(289)  评论(0编辑  收藏  举报