java thread wait
「Java thread wait」指的是 Java 多线程编程中让线程进入等待状态的相关用法,核心涉及 Object 类的 wait()、notify() 和 notifyAll() 方法。它和线程同步、共享资源协调以及生产者-消费者这类经典并发场景密切相关。
基本含义与用途
wait() 的作用是让当前线程释放持有的对象锁,并进入该对象的等待集,直到其他线程调用同一对象的 notify() 或 notifyAll() 把它唤醒。它通常与 synchronized 配合使用:线程先获得对象监视器,再在条件不满足时调用 wait() 等待,条件满足后由另一线程通知。这样做的目的是避免线程空转轮询,让多个线程在共享状态变化时有序协作。需要注意,wait() 必须写在 synchronized 块或方法内,否则会抛出 IllegalMonitorStateException。
常见问题
最典型的问题是虚假唤醒:线程可能在未被 notify 的情况下醒来,因此等待条件应该放在 while 循环里反复检查,而不是用 if 只判断一次。另一个常见错误是调用 wait() 时没有持有对应对象的锁,或者用错对象——等待和通知必须针对同一个监视器。还有人混淆 wait() 与 sleep():sleep() 不释放锁,只是暂停一段时间;wait() 会释放锁并依赖通知。此外,notify() 只随机唤醒一个等待线程,若多个线程等待不同条件,可能唤醒错对象,此时应优先考虑 notifyAll() 或改用更高级的并发工具。
怎么判断与怎么选
如果只是让线程暂停固定时间,用 sleep() 或定时任务即可;如果需要线程之间基于共享状态互相协调,才考虑 wait/notify。使用时坚持三个习惯:在 synchronized 内调用、用 while 包裹条件判断、确保等待与通知针对同一对象。若逻辑较复杂,比如需要队列、信号量或更清晰的条件等待,java.util.concurrent 包里的 BlockingQueue、Condition、CountDownLatch 等通常比裸用 wait/notify 更安全、更易读。判断标准很简单:代码越依赖手工加锁和通知,越容易出错,优先选现成的并发组件。