JUC Condition

在Java中,Condition 接口是与 Lock 配合使用的一个重要工具,它提供了类似于传统同步代码块(通过 synchronized 关键字)中的 wait()notify()notifyAll() 方法的功能,但更加灵活和强大。Condition 对象必须与一个 Lock 对象关联,这使得它们可以提供更细粒度的锁定控制。

主要方法

  • await():使当前线程等待,并且在该线程从 await 返回前,它必须重新获得与 Condition 相关的锁。
  • signal():唤醒一个等待在 Condition 上的线程。
  • signalAll():唤醒所有等待在 Condition 上的线程。

示例代码

下面是一个简单的示例,展示了如何使用 Condition 来实现生产者-消费者模式:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SimpleProducerConsumer {

    private static final Lock lock = new ReentrantLock();
    private static final Condition canProduce = lock.newCondition(); // 生产条件
    private static final Condition canConsume = lock.newCondition(); // 消费条件
    private static boolean available = false; // 标识是否有数据可用

    public static void main(String[] args) {
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                lock.lock();
                try {
                    while (available) { // 如果有数据未被消费,则等待
                        System.out.println("Buffer is full, waiting...");
                        canProduce.await();
                    }
                    available = true; // 生产数据
                    System.out.println("Produced: " + i);
                    canConsume.signal(); // 通知消费者可以消费了
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                }
                try {
                    Thread.sleep(100); // 模拟生产时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                lock.lock();
                try {
                    while (!available) { // 如果没有数据可消费,则等待
                        System.out.println("Buffer is empty, waiting...");
                        canConsume.await();
                    }
                    available = false; // 消费数据
                    System.out.println("Consumed");
                    canProduce.signal(); // 通知生产者可以生产了
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                } finally {
                    lock.unlock();
                }
                try {
                    Thread.sleep(200); // 模拟消费时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });

        producer.start();
        consumer.start();
    }
}
This article was updated on