【JUC-7】ReentrantLock (可重入锁)基础

news2025/1/20 20:04:45

ReentrantLock (可重入锁)

ReentrantLock实现了Lock接口, 内部通过继承AQS, 实现了一个同步器. 可以通过同步器来创建Condition条件变量, 可以用作容器, 存放不同条件的等待线程.

说明ReentrantLock与AQS的关系 类图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kNl3dfGd-1688483369185)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1688306634769.png)]

相对于synchronized, 都支持可重入. 它还具备如下特点:

  1. 可重入性:与synchronized关键字一样,ReentrantLock是可重入的,即同一个线程可以多次获取同一个锁而不会造成死锁。
  2. 公平性选择:ReentrantLock提供了公平锁和非公平锁的选择。公平锁会按照线程的请求顺序来获取锁,而非公平锁则不保证公平性,可能导致某些线程长时间等待。
  3. 锁获取和释放:使用ReentrantLock可以通过lock()方法获取锁,并通过unlock()方法释放锁。需要注意的是,获取锁后一定要在合适的地方释放锁,通常使用finally块来确保锁的释放。
  4. 条件变量:ReentrantLock提供了条件变量(Condition)的支持,通过newCondition()方法创建条件变量。条件变量可以让线程在特定的条件下等待或被唤醒,常与锁配合使用。
  5. 中断响应:ReentrantLock支持对线程的中断响应。在等待锁的过程中,可以通过调用lockInterruptibly()方法使线程对中断作出响应。
  6. 锁的可见性:与synchronized关键字一样,ReentrantLock同样保证了锁的可见性,即当一个线程释放锁时,对应的变量修改将对其他线程可见。

lockInterruptibly() :

是一个可以被打断的获取锁操作, 相当于是支持interrupt()方法的lock()方法. 普通的lock()方法如果被其他线程阻塞, 是无法通过interrupt()方法打断的, lockInterruptibly()方法, 是在加锁的时候如果被阻塞, 允许被打断.

Condition :

Condition是条件变量对象, 相当于是一个存放等待线程的容器, 比如在线程池中, 就会使用到Condition, 来存放不同的工作线程.

阻塞方法: await() 相当于 object对象的wait()

唤醒方法: signal() 相当于 object对象的 notify()

使用方法: 使用condition之前, 必须调用ReentrantLock对象的lock方法, 之后调用condition.await() 方法, 就把该线程加到condition对象中等待了, 后续执行signal() 方法, 就会从condition容器中随机唤醒一个线程, 继续执行

线程池是如何使用Condition的?

线程池没有直接使用Condition, 而是通过缓冲队列来使用Condition, 让线程没有任务执行时, 进入wait状态, 当有任务时, 会被唤醒执行任务.

例如, 在ArrayBlockingQueue队列中, 维护了两个condition, 一个是notEmpty, 当线程池调用队列的take方法获取任务执行的时候, 队列会判断当前队列中是否存在等待中的任务, 如果存在, 则取出执行, 如果没有, 则进入notEmpty Condition等待. 源码如下

线程池从队列获取任务, 队列中没任务, 则线程进入notEmpty等待

    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            // 队列中任务数量为0
            while (count == 0)
                // 进入notEmpty等待
                notEmpty.await();
            // 如果不为0 , 取出执行任务
            return dequeue();
        } finally {
            lock.unlock();
        }
    }

线程往队列中加入任务时, 如果队列满了, 则进入notFull中等待

    public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            enqueue(e);
        } finally {
            lock.unlock();
        }
    }
  1. notEmpty条件:用于控制任务队列中是否有任务可执行的条件。当任务队列为空时,线程池的工作线程会等待在notEmpty条件上,直到有新的任务被提交到任务队列中,此时会调用notEmpty.signal()方法来通知等待的工作线程继续执行任务。
  2. notFull条件:用于控制任务队列中是否还有空间可以接受新的任务的条件。当任务队列满时,如果线程池的最大线程数未达到限制,新提交的任务会直接创建新的工作线程来执行。当任务队列中有空闲位置时,线程池的工作线程会等待在notFull条件上,直到有新的任务被提交或者有工作线程被空闲释放,此时会调用notFull.signal()方法来通知等待的工作线程继续执行任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/718921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法练习】24:凯撒密码

一、凯撒密码介绍: 采用替换的方式对英文字母进行处理,将每一个英文字符循环替换为字母表序列中该字符的后面的第三个字符,即循环右移3位。 明文字母表:ABCDEFGHIJKLMNOPQRSTUVWXYZ 密文字母表:DEFGHIJKLMNOPQRSTUV…

微信小程序如何读取本地云存储txt数据,避免乱码

第一步 找到你的txt文件,重命名为json文件 第二步 上传到云存储中,获取File ID 第三步 编写js代码 相关技术文档: https://developers.weixin.qq.com/miniprogram/dev/api/file/FileSystemManager.readFile.html onShow(){wx.cloud.d…

《Redis 核心技术与实战》课程学习笔记(三)

高性能 IO 模型:为什么单线程 Redis 能那么快? Redis 是单线程,主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的,这也是 Redis 对外提供键值存储服务的主要流程。但 Redis 的其他功能,比如持久化、异步删…

CDS Core Data Services S4 CDS view--2

7.2 怎么加注释 首先要看懂注释,comparefilter 一般都是true,这样在association 里的join只被验证一次,如果是FALSE就会不停的被验证。 preservekey, 验证和数据库表的key是否一致。 authorizationcheck, 需要验证权限。不过我们没有设access control…

STM32F1 GPIO 简介

GPIO 是控制或者采集外部器件的信息的外设,即负责输入输出。它按组分配,每组 16 个 IO 口,组数视芯片而定。STM32F103ZET6 芯片是 144 脚的芯片,具有 GPIOA、GPIOB、GPIOC、 GPIOD、GPIOE、GPIOF 和 GPIOG 七组 GPIO 口&#xff0…

13---罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#xf…

【DBA课程-笔记】MongoDB入门到云上开发

课程目的:成为专业MongoDB的DBA nosql第一:MongoDB 一、讲师: 二、课程目录 第1章:MongoDB数据库入门 第2章:MongoDB数据数据查询与分析 第3章:MongoDB数据库核心知识 第4章:MongoDB数据库管…

时间序列预测 | Matlab基于粒子群算法优化门控循环单元(PSO-GRU)的时间序列预测,PSO-GRU时间序列预测,单列数据集

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab基于粒子群算法优化门控循环单元(PSO-GRU)的时间序列预测,PSO-GRU时间序列预测,单列数据集。 优化参数为学习率,隐藏层节点个数,正则化参数,要求2020b及以上版本&#

Redhat7.6安装mysql5.7

环境准备:硬盘剩余空间最少8G,内存剩余最少2G Mysql官网下载地址:https://dev.mysql.com/downloads/mysql/5.7.html 在Mysql官网下载列表中选择需要安装的版本: RedHat7.6安装MySQL5.7 安装之前,先要保证系统环境是干净的,不能存…

Dual In-Line Package(双列直插式封装)和Pin Grid Array Package(针栅阵列插入式封装)

DIP封装示意图 1.Dual In-Line Package(双列直插式封装) DIP的详细介绍: 1.封装形式:DIP是一种插件式封装,它由一个狭长的塑料或陶瓷封装体组成,具有在两侧排列的引脚。引脚通常是分布均匀的&#xff0c…

17. 订单金额趋势分析

文章目录 题目需求思路一实现一实现二:使用 over(range)学习链接题目来源 题目需求 查询截止每天的最近3天内的订单金额总和以及订单金额日平均值,保留两位小数,四舍五入。 最近三天 的业务逻辑通常是基于当天往前推2天 期望结果如下&#x…

Kepware.KEPServer安装

1.1 Kepware.KEPServer安装 1.1.1 解压并安装 首先解压并安装KEPServerEX v4.500.465.zip,右键点击KEPServer执行文件进行安装,如图2-2-14所示, 图2-2-14 2) 运行KEPServer安装文件之后出现如图2-2-15所示:点击Next继续。 图2-2-15 3) 选择I accept the tems of the lice…

Keras-5-深度学习用于文本和序列-处理文本数据

深度学习用于文本和序列 说明: 本篇学习记录为:《Python 深度学习》第6章第1节(处理文本数据) 知识点: 深度学习处理文本或序列数据的基本方法是:循环神经网络 (recurrent neural network) 和 一维卷积神经网络 (1D convert)&…

Python中怎样用索引和切片取出字符串片段?

Python 语言为字符串中的元素编号,以实现对字符串中的单个字符或字符片段的索引。按照不同的方向,索引分为正向索引和逆向索引。假设字符串的长度为L,正向索引中字符串的字符编号从左至右由0递增为L-1,逆向索引中字符串的字符编号…

【雕爷学编程】Arduino动手做(151)---S12SD紫外线模块

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的&am…

022、数据库管理之数据迁移工具(DM)

DM Data Migration架构与原理适用场景下载安装组件编辑初始化配置文件执行部署命令查看DM集群检查DM集群情况启动集群 DM配置概览上游数据库(数据源)配置任务配置过滤配置分库分表合并迁移性能优化常见问题 dmctl检查与启动任务暂停任务恢复任务查询任务停止任务 实验部署DM集群…

Netty--聊天业务

:::info 提醒 : 本文相对比较乱, 主要是关于 Netty websocket 之类的聊天功能相关, 大家了解即可;有兴趣的 可以选读; 1.聊天模块细分微服务: 用户服务:处理用户身份验证、授权和管理。包括用户注册、登录、个人信息管理等功能。聊天服务:处理实时聊天功…

在markdown中或者CSDN中如何展示双下滑线

最近在CSDN中写文章时,遇到了一个问题,当我输入__proto__ 时,在展示的时候,下滑想不显示emm… 于是乎我一通翻找,发现原来不止csdn,markdown里也有这样的问题,并最终找到了解决办法&#xff01…

生成模型一文认识图像生成

最近看了一些图像生成的论文和博客,觉得要总结一下。本文主要介绍图像生成技术,包括研究背景、研究意义、相关应用、以及所用到的技术。 目录 一、背景与意义 二、图像生成应用 2.1 图像到图像的转换 2.2 文本到图像的生成 2.3 图像超分辨率 2.4 风…

转转闲鱼交易猫源码搭建

后台一键生成链接,后台管理 教程:解压源码,修改数据库config/Congig 不会可以看源码里有教程 下载程序:https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3