wait()方法与await()方法的区别

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

    • 更适合高并发场景。

posted @ 2024-11-19 15:20  luorx  阅读(1)  评论(0编辑  收藏  举报