首先,我们要知道wait()
、notify()
、notifyAll()
都是Object
的方法
我们先想一个问题
这三个方法真的在任何地方都能使用么?
其实不是的。
他们都有一个前提:在拿到锁的情况下,才能使用。
我们就直接用代码来看下
/**
* 没拿到锁的情况下,不管是调用wait()、notify()、notifyAll()都会抛出IllegalMonitorStateException异常
*
* @throws InterruptedException
*/
@Test
public void test() throws InterruptedException {
Object o = new Object();
o.wait();
// o.notify();
// o.notifyAll();
}
结果如下:
正确使用姿势
/**
* 在synchronized内部调用wait()、notify()、notifyAll()
*
* @throws InterruptedException
*/
@Test
public void test() throws InterruptedException {
Object o = new Object();
synchronized (o) {
o.wait();
// o.notify();
// o.notifyAll();
}
其实这里还会有个问题,比如:现在有两把锁A、B,我锁的是A,然后用A.wait(),这也是会抛出IllegalMonitorStateException异常的
@Test
public void test() throws InterruptedException {
Object A = new Object();
Object B = new Object();
synchronized (A) {
B.wait();
}
}
结果如下:
结论
wait()、notify()、notifyAll()只能在拿到锁的情况下使用,也就是synchronized(){}内部使用。假如锁的是A,就必须用A.wait(),A.notify(),A.notifyAll(),不能用B.wait(),B.notify(),B.notifyAll()
开心一刻
老师:“各位同学,觉得自己很蠢的请站起来。”
同学们互相看了看,都不敢站起来,只有一个勇敢的站了起来
老师:“这位同学,你觉得自己很蠢吗?”
学生:“不是的,老师,我只是不想让你一个人站着! ”