实质上,Java 的 Object 类本身就是监视者对象,Java 语言对于这样一个典型并发设计模式做了内建的支持。不过,在 Java 里,我们已经看不到了我们在 C++ 一节所讨论的区域锁与条件变量的概念。下图很好地描述了 Java Monitor 的工作机理。
![java Object 类中 notify() ,notifyAll() ,wait() - TROY - TROY](http://img609.ph.126.net/dvLlV-8dLQ5iOYSacej_wQ==/1899956092799131914.jpg)
线程如果获得监视锁成功,将成为该监视者对象的拥有者。在任一时刻内,监视者对象只属于一个活动线程 (Owner) 。拥有者线程可以调用 wait 方法自动释放监视锁,进入等待状态.
1. wait() 方法:
要调用一个对象的wait()方法,只有当前线程获取了这个对象的锁,换句话说一定要在这个对象的同步方法或以这个对象为参数的同步块中.当一个线程调用了wait() 方法后,这个线程就进入了这个对象的休息室(waitset),这是一个虚拟的对象,但JVM中一定存在这样的一个数据结构用来记录当前对象中有哪些程线程在等待。然后它就会释放锁,让其它线程来获取这个锁.
这个线程只能等待其它线程调用notity[All]来唤醒.
但是如果调用的是有参数的wait(time)方法,则线程会在休息室中等待这个时间后自动唤醒.
class Test{
public synchornized void test(){
//获取条件,int x 要求大于100;
while(x < 100) // 注意这里是while 每次被唤醒后,还是要检查条件是否满足
wait();
perform(); // 执行操作
}
}
2. notify() notifyAll() 方法:
这两个方法都是把某个对象上休息区内的线程唤醒,notify只能唤醒一个,但究竟是哪一个不能确定,而notifyAll则唤醒这个对象上的休息室中所有的线程.
一般为了保险起见,我们在绝对多数时候应该使用notifiAll(),除非你明确知道只唤醒其中的一个线程.