wait()
方法与 await()
方法的区别
这两种方法都与线程或异步任务的协调有关,但它们用于不同的场景,并且行为和语法都不相同。
1. wait()
方法
定义与场景
-
所属:
java.lang.Object
类。 -
用途:用于线程间的通信,通常与
notify()
或notifyAll()
方法一起使用。 -
场景:在多线程程序中,一个线程等待某些条件满足,而另一个线程通知它继续执行。
关键特点
-
必须在同步块(
synchronized
)或同步方法中调用,否则会抛出IllegalMonitorStateException
。 -
调用
wait()
的线程会释放锁并进入 等待状态,直到另一个线程调用notify()
或notifyAll()
唤醒它。 -
属于阻塞操作,调用后线程会停止运行,直到被唤醒。
语法
synchronized (lock) { lock.wait(); // 释放锁并进入等待状态 }
示例
class WaitNotifyExample { private static final Object lock = new Object(); public static void main(String[] args) { Thread t1 = new Thread(() -> { synchronized (lock) { try { System.out.println("Thread 1 is waiting..."); lock.wait(); System.out.println("Thread 1 is resumed!"); } catch (InterruptedException e) { e.printStackTrace(); } } }); Thread t2 = new Thread(() -> { synchronized (lock) { System.out.println("Thread 2 is notifying..."); lock.notify(); } }); t1.start(); t2.start(); } }
输出
Thread 1 is waiting...
Thread 2 is notifying...
Thread 1 is resumed!
2. await()
方法
定义与场景
所属:java.util.concurrent.locks.Condition 接口。 用途:用于高级线程协调,通常结合 ReentrantLock 使用。 场景:细粒度控制线程的等待和唤醒操作,在并发编程中提供更灵活的机制。 关键特点 必须在锁对象(如 ReentrantLock)的条件中使用,不能在普通的同步块中使用。 与 wait() 类似,调用线程会释放锁并进入等待状态,直到被其他线程通过 signal() 或 signalAll() 唤醒。 提供更好的线程通信控制,可以使用多个条件(Condition),而不像 wait() 只能针对一个对象锁。 语法 ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); lock.lock(); try { condition.await(); // 释放锁并进入等待状态 } finally { lock.unlock(); } 示例 import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; class AwaitSignalExample { private static final ReentrantLock lock = new ReentrantLock(); private static final Condition condition = lock.newCondition(); public static void main(String[] args) { Thread t1 = new Thread(() -> { lock.lock(); try { System.out.println("Thread 1 is waiting..."); condition.await(); System.out.println("Thread 1 is resumed!"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }); Thread t2 = new Thread(() -> { lock.lock(); try { System.out.println("Thread 2 is signaling..."); condition.signal(); } finally { lock.unlock(); } }); t1.start(); t2.start(); } }
输出
Thread 1 is waiting...
Thread 2 is signaling...
Thread 1 is resumed!
对比总结
特性 | wait() | await() |
---|---|---|
所属类 | java.lang.Object |
java.util.concurrent.locks.Condition |
使用锁类型 | Java 内置锁(synchronized ) |
显式锁(ReentrantLock ) |
等待/唤醒方法 | wait() / notify() / notifyAll() |
await() / signal() / signalAll() |
是否释放锁 | 释放锁,等待被通知 | 释放锁,等待被通知 |
灵活性 | 只能使用一个对象锁,功能较为简单 | 可以为不同条件创建多个 Condition ,功能更强大 |
线程安全控制粒度 | 粒度较粗 | 粒度更细 |
是否支持中断 | 可以通过 InterruptedException 被中断 |
同样支持 InterruptedException |
选择建议
-
wait()
:-
如果是传统的
synchronized
代码块,使用wait()
即可。 -
适合简单的线程间协调。
-
-
await()
:-
如果需要更复杂的线程控制(如多个条件或高级同步机制),推荐使用
await()
和ReentrantLock
。 -
更适合高并发场景。
-