obj.wait() :让进入 object 监视器的线程到 waitSet 等待
obj.wait(long timeout):有时限的等待,等够了就继续向下执行
obj.notify(): 在 object 上正在 waitSet 等待的线程中挑一个唤醒(随机,不确定哪个)
obj.notifyAll() :让 object 上正在 waitSet 等待的线程全部唤醒
import lombok.extern.slf4j.Slf4j;
import static utils.Sleeper.sleep;
/**
* 等待唤醒
* wait notify
*/
@Slf4j(topic = "c.TestWaitNotify")
public class TestWaitNotify {
final static Object obj = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
}, "t1").start();
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
}, "t2").start();
// 主线程两秒后执行
sleep(2);
log.debug("唤醒 obj 上其它线程");
synchronized (obj) {
// obj.notify(); // 唤醒obj上一个线程(随机,不确定哪个)
obj.notifyAll(); // 唤醒obj上所有等待线程
}
}
}
Owner 线程发现条件不满足,调用 wait 方法,即可进入 WaitSet 变为 WAITING 状态
BLOCKED 和 WAITING 的线程都处于阻塞状态,不占用 CPU 时间片
BLOCKED 线程会在 Owner 线程释放锁时唤醒
WAITING 线程会在 Owner 线程调用 notify 或 notifyAll 时唤醒,但唤醒后并不意味者立刻获得锁,仍需进入
EntryList 重新竞争