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();
}
}