等待/通知机制

一个线程修改了一个对象的值,另一个线程感知到了变化,然后进行相应的操作,整个过程开始于一个线程,最终执行又是另一个线程,前者是生产者,后者是消费者。Java如何实现?

一种办法是让消费者线程不断的循环检查变量是否符合预期。

1
2
3
4
5
6
while(value!=desire)
{
Thread.sleep(1000);
}
doSomething();
存在的问题:难以确保及时性,难以降低开销。

使用内置的等待/通知机制解决问题

等待/通知的相关方法任意Java对象都具备,因为方法定义在Java.lang.Object上。

等待通知机制,指一个线程A调用了对象O的wait()方法进入等待状态,而另一个线程B调用了对象O的notify()方法或者notifyAll()方法,线程A收到通知后从对象O的wait()方法返回,进而执行后续操作,上述两个线程通过对象O完成交互,而对象上的wait()和notify/notifyAll()的关系就像开关信息一样,用来等待方和通知方之间的交互工作。

调用wait() notify() notifyAll() 时注意的细节

  • 调用wait()方法后会释放对象的锁。
  • 使用wait() notify() notifyAll() 时需要先对调用对象加锁。
  • 调用wait() 后,线程状态由running变为waiting.并将当前线程放置到对象的等待队列。
  • notify() notifyAll()方法调用后,等待线程依旧不会从wait返回,需要调用notify()或 notifyAll()的线程释放锁以后,等待线程才有机会从wait返回。
  • 接上一条,从wait方法返回的前提是获得了调用对象的锁(也就是调用notify()释放锁,调用wait()的重新获得锁,才有可能返回)。
  • notify()方法将等待队列中一个等待线程从等待队列移到同步队列中。而notifyall方法则将等待队列中所有线程移到同步队列,被移动的线程从waiting变为blocked