由于线程之间是抢占式执⾏的, 因此线程之间执⾏的先后顺序难以预知.
但是实际开发中有时候我们希望合理的协调多个线程之间的执⾏先后顺序
完成这个协调⼯作, 主要涉及到三个⽅法
•
wait() / wait(long timeout): 让当前线程进⼊等待状态.
•
notify() / notifyAll(): 唤醒在当前对象上等待的线程.
注意: wait, notify, notifyAll 都是 Object 类的⽅法
wait()⽅法
wait 做的事情:
•
使当前执⾏代码的线程进⾏等待. (把线程放到等待队列中)
•
释放当前的锁
•
满⾜⼀定条件时被唤醒, 重新尝试获取这个锁.
wait 要搭配 synchronized 来使⽤. 脱离 synchronized 使⽤ wait 会直接抛出异常.
wait 结束等待的条件:
•
其他线程调⽤该对象的 notify ⽅法.
•
wait 等待时间超时 (wait ⽅法提供⼀个带有 timeout 参数的版本, 来指定等待时间).
•
其他线程调⽤该等待线程的 interrupted ⽅法, 导致 wait 抛出
InterruptedException
异常

这个时候就 需要使⽤到了另外⼀个⽅法唤醒的⽅法notify()。
notify()⽅法
notify ⽅法是唤醒等待的线程.
•
⽅法notify()也要在同步⽅法或同步块中调⽤,该⽅法是⽤来通知那些可能等待该对象的对象锁的其 它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。
•
如果有多个线程等待,则有线程调度器随机挑选出⼀个呈 wait 状态的线程。(并没有 "先来后到")
•
在notify()⽅法后,当前线程不会⻢上释放该对象锁,要等到执⾏notify()⽅法的线程将程序执⾏
完,也就是退出同步代码块之后才会释放对象锁
代码⽰例: 使⽤notify()⽅法唤醒线程

notifyAll()⽅法
notify⽅法只是唤醒某⼀个等待线程. 使⽤notifyAll⽅法可以⼀次唤醒所有的等待线程

把 notify 替换成 notifyAll
注意: 虽然是同时唤醒 3 个线程, 但是这 3 个线程需要竞争锁. 所以并不是同时执⾏, ⽽仍然是有先有后 的执⾏.