await 和 wait 是两个在 Java 用于线程同步的关键字。它们的功能是让线程在满足某些条件后继续执行。虽然它们的功能相似,但在使用上存在一些差异。
首先,让我们来看看 await 关键字。它是 Java 5 用于配合使用的新特性 Lock 和 Condition 实现线程等待和唤醒的功能。在使用 await 在此之前,我们需要先得到它 Lock 对象,并通过 Lock 对象的 newCondition 创建一种方法 Condition 对象。
await 该方法将当前线程放入等待队列,然后释放 Lock 对象的锁有机会获得并执行其他线程。当满足某些条件时,我们可以调用它们 Condition 对象的 signal 或 signalAll 方法唤醒等待队列中的线程。
以下是一个用途 await 和 signal 实现生产者消费者模型的例子:
import java.util.LinkedList;import java.util.Queue;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ProducerConsumer { private final int capacity; private final Queue<Integer> queue; private final Lock lock; private final Condition notEmpty; private final Condition notFull; public ProducerConsumer(int capacity) { this.capacity = capacity; this.queue = new LinkedList<>(); this.lock = new ReentrantLock(); this.notEmpty = lock.newCondition(); this.notFull = lock.newCondition(); } public void produce(int num) throws InterruptedException { lock.lock(); try { while (queue.size() == capacity) { notFull.await(); } queue.add(num); notEmpty.signal(); } finally { lock.unlock(); } } public int consume() throws InterruptedException { lock.lock(); try { while (queue.isEmpty()) { notEmpty.await(); } int num = queue.poll(); notFull.signal(); return num; } finally { lock.unlock(); } }}
在上面的代码中,我们使用了一个容量 capacity 当队列满时,生产者需要等待生产者生产的数据,当队列空时,消费者需要等待。通过使用 await 和 signal 我们可以实现生产者和消费者之间的同步。
接下来,我们来看看。 wait 关键字。是的 Java 中 Object 该类的一种方法是让当前线程进入等待状态并释放对象的锁。通过调用对象 notify 或 notifyAll 方法,我们可以唤醒等待的线程。
以下是一个使用 wait 和 notify 实现生产者消费者模型的例子:
import java.util.LinkedList;import java.util.Queue;public class ProducerConsumer { private final int capacity; private final Queue<Integer> queue; public ProducerConsumer(int capacity) { this.capacity = capacity; this.queue = new LinkedList<>(); } public synchronized void produce(int num) throws InterruptedException { while (queue.size() == capacity) { wait(); } queue.add(num); notifyAll(); } public synchronized int consume() throws InterruptedException { while (queue.isEmpty()) { wait(); } int num = queue.poll(); notifyAll(); return num; }}
在上面的代码中,我们使用了一个容量 capacity 当队列满时,生产者需要等待生产者生产的数据,当队列空时,消费者需要等待。通过使用 wait 和 notifyAll 我们可以实现生产者和消费者之间的同步。
总结起来,await 和 wait 它们都是用于线程同步的关键字,它们可以让线程在满足某些条件后继续执行。await 是 Java 5 中引入的新特征需要配合 Lock 和 Condition 使用;而 wait 是 Object 可直接用于同步方法或同步代码块。
流程图如下:
flowchart TD subgraph await A[获取锁] --> B[判断条件] B -- 条件满足 --> C[执行] B -- 条件不满足 --> D[等待] C --> E[释放锁] D --> E end subgraph wait F[获取锁] --> G[判断条件] G -- 条件满足 --> H[执行] G -- 条件