扰扰博客

LockConditionDemo

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;

/**
 * Lock + Condition 实现生产者-消费者模型
 */
public class LockConditionDemo {
    // 缓冲区(队列),模拟生产/消费的容器
    private final Queue<Integer> queue = new LinkedList<>();
    // 缓冲区最大容量
    private static final int MAX_CAPACITY = 5;
    // 普通锁(ReentrantLock 是 Lock 的常用实现)
    private final Lock lock = new ReentrantLock();
    // 两个 Condition:分别控制生产者等待(队列满)和消费者等待(队列空)
    private final Condition notFull = lock.newCondition();  // 队列不满的条件
    private final Condition notEmpty = lock.newCondition(); // 队列不空的条件

    // 生产者方法:生产数据
    public void produce(int num) throws InterruptedException {
        // 1. 获取锁(必须先锁,才能用 Condition)
        lock.lock();
        try {
            // 2. 循环检查条件:队列满时,生产者等待
            while (queue.size() == MAX_CAPACITY) {
                System.out.println("队列已满,生产者等待...");
                notFull.await(); // 释放锁,等待消费者唤醒
            }
            // 3. 生产数据
            queue.offer(num);
            System.out.println("生产者生产:" + num + ",当前队列大小:" + queue.size());
            // 4. 唤醒等待的消费者(队列从空→非空)
            notEmpty.signal();
        } finally {
            // 5. 释放锁(必须在finally中,避免异常导致锁无法释放)
            lock.unlock();
        }
    }

    // 消费者方法:消费数据
    public Integer consume() throws InterruptedException {
        lock.lock();
        try {
            // 1. 循环检查条件:队列空时,消费者等待
            while (queue.isEmpty()) {
                System.out.println("队列为空,消费者等待...");
                notEmpty.await(); // 释放锁,等待生产者唤醒
            }
            // 2. 消费数据
            Integer num = queue.poll();
            System.out.println("消费者消费:" + num + ",当前队列大小:" + queue.size());
            // 3. 唤醒等待的生产者(队列从满→非满)
            notFull.signal();
            return num;
        } finally {
            lock.unlock();
        }
    }

    // 测试
    public static void main(String[] args) {
        LockConditionDemo demo = new LockConditionDemo();

        // 启动生产者线程
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    demo.produce(i);
                    Thread.sleep(500); // 模拟生产耗时
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "生产者").start();

        // 启动消费者线程
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    demo.consume();
                    Thread.sleep(1000); // 模拟消费耗时
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "消费者").start();
    }
}

 

posted @ 2026-01-19 14:42  扰扰  阅读(4)  评论(0)    收藏  举报