当前位置: 首页 > news >正文

ReentrantLock中的Condition

1.ReentrantLock,也被称为“可重入锁”,是一个同步工具类

Sync类是 ReentrantLock(可重入锁)中的一个​​ ​​内部抽象类​​,它是 ReentrantLock实现锁功能(比如加锁、解锁、可重入性等)的​​核心基础类​​,并使用了 ​​Java 底层的 AQS(AbstractQueuedSynchronizer,抽象队列同步器)​​ 来实现线程同步。

2. Condition 是什么?

Condition是 java.util.concurrent.locks包中的一个 ​​接口​​,它代表了一个 ​​条件变量​​,用于线程间的 ​​协调与通信​​。

它提供了一组方法,类似于 Object的 wait / notify / notifyAll,但是更强大、更灵活,而且与 ReentrantLock绑定使用。可以实现多个等待队列。

3.获取 Condition 的方式:

你不能直接 new 一个 Condition,而是通过 ReentrantLock对象的 newCondition()方法来创建:

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();  // 创建一个条件变量

4. Condition 的使用示例(经典:生产者消费者)

  场景:

  • 有一个缓冲区(比如队列),容量有限

  • ​生产者​​往里放数据,如果满了,就等待

  • ​消费者​​从里拿数据,如果空了,就等待

  • 使用 ​​两个 Condition​​:

    • notFull:表示“缓冲区不满”,生产者等待这个条件

    • notEmpty:表示“缓冲区不空”,消费者等待这个条件

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class ProducerConsumerWithCondition {private final Queue<Integer> queue = new LinkedList<>();private final int capacity = 5;private final ReentrantLock lock = new ReentrantLock();private final Condition notFull = lock.newCondition();   // 缓冲区不满private final Condition notEmpty = lock.newCondition(); // 缓冲区不空// 生产者public void produce(int item) throws InterruptedException {lock.lock();try {while (queue.size() == capacity) {System.out.println("队列已满,生产者等待...");notFull.await(); // 缓冲区满了,生产者等待 notFull 条件}queue.add(item);System.out.println("生产: " + item + ",队列大小 = " + queue.size());notEmpty.signal(); // 通知消费者,队列不空了} finally {lock.unlock();}}// 消费者public int consume() throws InterruptedException {lock.lock();try {while (queue.isEmpty()) {System.out.println("队列为空,消费者等待...");notEmpty.await(); // 缓冲区空了,消费者等待 notEmpty 条件}int item = queue.remove();System.out.println("消费: " + item + ",队列大小 = " + queue.size());notFull.signal(); // 通知生产者,缓冲区不满了return item;} finally {lock.unlock();}}
}
  • notFull:当队列满了,生产者调用 notFull.await()进入等待,​​释放锁​

  • notEmpty:当队列空了,消费者调用 notEmpty.await()进入等待,​​释放锁​

  • 当有新的数据被生产出来,调用 notEmpty.signal()唤醒等待的消费者

  • 当有数据被消费,调用 notFull.signal()唤醒等待的生产者

5.注意notFull.signal(); 与 lock.unlock();的区别

 notFull.signal():它仅仅是一个 “通知” 操作,告诉等待的线程可以尝试重新竞争锁了,但不会释放任何锁!​

// 生产者
lock.lock();
try {while (queue.size() == capacity) {notFull.await(); // 缓冲区满了,生产者等待}queue.add(item);notEmpty.signal(); // 通知消费者:缓冲区非空了,可以消费了
} finally {lock.unlock(); // ✅ 必须要释放锁!
}

1. ​notFull.signal()做了什么?​

  • 假如消费者消费了一个元素,队列不再满

  • 消费者调用:notFull.signal();

  • 这个方法会 ​​唤醒一个正在 notFull.await()上等待的生产者线程​

  • 但注意:​​这个唤醒只是让生产者线程从等待队列移到了锁的竞争队列,它仍然需要获取锁之后才能继续运行!​


2. ​lock.unlock()做了什么?​

  • 生产者或消费者在完成自己的操作后,​​必须调用 lock.unlock()

  • 这个方法会 ​​释放当前线程持有的锁​

  • 一旦锁被释放,​​其他正在等待获取该锁的线程(比如刚被唤醒的生产者)就能获取锁并继续执行了​

http://www.dtcms.com/a/474452.html

相关文章:

  • 基于Spring Boot + Vue 3的乡村振兴综合服务平台架构设计与实现
  • 专门做门的网站软件开发公司专业的有哪些
  • 网站不用了 怎么关闭吗做资源网站怎么赚钱
  • J东h5st逆向实战
  • 营销型网站如何制作软件设计师含金量高吗
  • 【MySQL】从零开始了解数据库开发 --- 基本查询
  • LeetCode进阶算法题解详解
  • 构造器是什么
  • docker desktop安装(windows os)
  • 免费的网站域名查询app国外的营销网站有哪些
  • 大模型基础入门与 RAG 实战:从理论到 llama-index 项目搭建(有具体代码示例)
  • 保定网站建设报价网页设计图片变圆角
  • 网站首页没收录大连网站流量优化定制
  • 基于CAN的UDS诊断服务
  • C++ : AVL 树之 右左双旋(第四章)
  • 南阳网站制作哪家好西安专业网站开发哪家好
  • 在 Windows PowerShell(pwsh)中配置 Oh My Posh + Conda 环境美化与性能优化
  • 小榄做网站新专业建设的重点任务
  • 把AI“浓缩”到1KB:超紧凑型决策树在MCU上的极限优化实战
  • Spring Boot 原理篇
  • 站酷网免费素材图库官网竣工验收全国公示平台
  • eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
  • 【Chrome插件】‘顾得助手’ 新功能介绍
  • 【控制系统建模与分析#1】电系统建模
  • 【Linux系统】9. 基础开发工具(三)
  • 付费网站做推广哪个好wordpress 顶部导航
  • 什么是AIGC?AIAIGCAGI什么区别?
  • NLP入门
  • 最低成本做企业网站 白之家杭州动漫设计公司最新招聘
  • 外汇跟单网站建设西安软件培训