线程之间协调工作的方式
快速回顾
- wait(),notify(),notifyAll()这三个方法作用:等待,唤醒,唤醒全部
- 同步队列(锁池),当一个线程拥有一个对象方法的锁时,别的线程想调用该方法
时先进入该对象的同步队列,状态变为Blocked。
需要注意的点:
想要等待再唤醒,需要先对被调用者先加锁
notify()唤醒的时候,那边线程要先释放锁
sleep()不释放锁
基于等待通知模型的通信
等待/通知的相关方法是任意Java对象都具备的,因为这些方法被定义在所有对象的超类java.lang.Object上。
相关API
- notify: 通知一个对象上等待的线程,使其从wait方法返回,而返回的前提是该线程获取到了对象的锁
- notifyAll: 通知对象上所有等待的线程,使其从wait方法返回
- wait: 使线程进入WAITING(后面线程的生命周期讲)状态,只有等待另一个线程通知或者被中断才返回,需要注意的是,调用wait方法后需要释放对象的锁
- wait(long): 和wait类似,加入了超时时间,超时了还没被通知就直接返回
- wait(long, int): 纳秒级,不常用
一些需要注意的点:
- 使用wait()、notify()和notifyAll()时需要先对调用对象加锁。
- 调用wait()方法后,线程状态由RUNNING变为WAITING,并将当前线程放置到对象的等待队列,释放锁。
- notify()或notifyAll()方法调用后,等待线程不会立即从wait()返回,需要调用notify()或notifAll()的线程释放锁之后,等待线程才有机会从wait()返回。
- notify()方法将等待队列中的一个等待线程从等待队列中移到同步队列中,而notifyAll()方法则是将等待队列中所有的线程全部移到同步队列,被移动的线程状态由WAITING变为BLOCKED。
- 从wait()方法返回的前提是获得了调用对象的锁。
小Demo
等待通知模型
两个线程A和B,操作同一个对象,(前提持锁)A释放锁进入等待队列,B拿到锁(前提)通知唤醒它



模型
等待者
synchronized (对象) {while (不满足条件) {对象.wait()}处理逻辑}
通知者
synchronized (对象) {改变条件对象.notify();}
基于Condition的通信
有界队列
消费者,生产者
非空,不满
生产者判断满了吗?满了就等待让消费者拿出数据,没有就继续塞数据
消费者判断空了吗?空了就等待让生产者塞数据,没有就往出拿



