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

java并发编程 ReentrantLock详解

文章目录

    • 1 概要
    • 2 相关文章
    • 3 例子
    • 4 方法详解
      • 4.1 lock()
      • 4.2 unlock()
      • 4.3 tryLock()
      • 4.4 其他
      • 公平锁
    • 总结

1 概要

ReentrantLock 通过实现Lock接口的行为,提供锁机制。但是实现委托给了内部的Sync,Sync extends AbstractQueuedSynchronizer,继承了AQS的能力。此时还提供两个具体的实现,公平锁和非公平锁。首先如果对AQS不了解,请看java并发编程 AbstractQueuedSynchronizer(AQS)详解一。下文会对上述几个点进行详解内部原理

2 相关文章

  1. java并发编程 AbstractQueuedSynchronizer(AQS)详解一
  2. java并发编程 AbstractQueuedSynchronizer(AQS)详解二

3 例子

ReentrantLock 注释上的例子。。。。
如果lock没有被阻塞住就代表获取到锁,然后执行业务逻辑。最终finally 里释放锁,防止抛异常

public class X {private final ReentrantLock lock = new ReentrantLock();    // ...     public void m() {      lock.lock();// block until condition holds      try {        // ... method body     } finally {        lock.unlock()  ;    }    }  
}

4 方法详解

先看非公平锁实现。
先说下在ReentrantLock里上锁是通过state变量,如果是0,且从0原子变成1成功代表获取成功,如果重入则state + 1,释放锁就减1,0的时候释放锁。

4.1 lock()

public void lock() {//委托给sync执行sync.lock();
}
//非公平锁实现
final void lock() {//先自己尝试设置成1 如果成功设置拥有锁的线程为自己if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());else//aqs 的acquire 若对aqs不熟悉的,请先看相关文章//他会进入tryAcquire(arg)的具体实现acquire(1);
}
protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);
}
//非公平的尝试加锁
final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//如果是0 尝试变成1,此时如果阻塞队列中有阻塞的线程,但是新的加锁线程还是有可能获取到锁的,//因为释放锁后只会从Head.next的Node去唤醒获取锁, 你后来的线程比先来的先拿到锁,公平吗? 非公平锁if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//可重入的实现。如果当前线程是自己,也就是lock拿到锁再lock直接state + 1, 因为独占锁,所以不需要原子性+1else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}//现在state不是0且持有锁的线程不是自己,尝试加锁失败return false;
}

4.2 unlock()

持有锁的线程释放锁

public void unlock() {sync.release(1);
}public final boolean release(int arg) {// aqs的抽象实现if (tryRelease(arg)) {//成功了会唤醒head.next线程Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}//释放失败 可重入的时候从5 -> 4return false;
}
protected final boolean tryRelease(int releases) {//不需要原子性操作是因为当前持有锁int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;//state = 0 的时候代表释放锁if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;
}

4.3 tryLock()

对比lock 其实就没有进入阻塞队列的逻辑。比较简单

public boolean tryLock() {return sync.nonfairTryAcquire(1);
}

4.4 其他

其他方法都可类比lock 和 unlock。如阻塞一段时间的等。

公平锁

公平锁核心方法实现,对比下和非公平锁的区别就可以看到,多了!hasQueuedPredecessors()
这个方法。很清晰。

protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {//区别在这,如果阻塞队列有阻塞的线程,就不去争抢,会return falseif (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)throw new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;
}
//阻塞队列中没有阻塞的线程
public final boolean hasQueuedPredecessors() {Node t = tail;Node h = head;Node s;return h != t &&((s = h.next) == null || s.thread != Thread.currentThread());
}

总结

ReentrantLock 本质上是基于AQS实现的可重入锁,且提供了公平和非公平的机制,逻辑较为简单,需要对AQS熟练掌握。

相关文章:

java并发编程 ReentrantLock详解

文章目录 1 概要2 相关文章3 例子4 方法详解4.1 lock()4.2 unlock()4.3 tryLock()4.4 其他公平锁 总结 1 概要 ReentrantLock 通过实现Lock接口的行为&#xff0c;提供锁机制。但是实现委托给了内部的Sync&#xff0c;Sync extends AbstractQueuedSynchronizer&#xff0c;继承…...

Java获取文件内容IO流

文章目录 InputStream和ReaderScannerNIO外传 一般读取文件类的使用字符流即可 InputStream和Reader InputStream和Reader是Java IO中的两个重要的抽象基类&#xff0c;InputStream是二进制流&#xff0c;Reader是字符流。使用InputStream或者Reader读取文件内容可以帮助我们…...

Java后端开发面试题——集合篇

ArrayList底层的实现原理是什么 底层数据结构 ArrayList底层是用动态的数组实现的 初始容量 ArrayList初始容量为0&#xff0c;当第一次添加数据的时候才会初始化容量为10 扩容逻辑 ArrayList在进行扩容的时候是原来容量的1.5倍&#xff0c;每次扩容都需要拷贝数组 添加逻…...

如何允许远程访问MySQL

许多网站和应用程序一开始都将web服务器和数据库后端托管在同一台机器上。不过&#xff0c;随着时间的推移&#xff0c;这样的设置可能会变得繁琐和难以扩展。一种常见的解决方案是通过设置远程数据库来分离这些功能&#xff0c;允许服务器和数据库在各自的机器上按自己的速度增…...

001图机器学习与图神经网络简介

文章目录 一. 无处不在的图二. 如何对图数据做信息挖掘三. 图神经网络四. 图机器学习常用的编程工具五. 图的可视化工具六. 常见的图数据库七. 图机器学习的应用举例八. 结束语 一. 无处不在的图 一切具有关联关系的数据都可以用图来表示。比如&#xff1a;交通网、知识图谱、…...

万级数据优化EasyExcel+mybatis流式查询导出封装

文章目录 前言.万级数据优化一. 直接上流式查询封装工具代码二. 传统分页导出查询三. 流式查询概念游标查询 前言.万级数据优化 我们不妨先给大家讲一个概念&#xff0c;利用此概念我们正好给大家介绍一个数据库优化的小技巧&#xff1a; 需求如下&#xff1a;将一个地市表的数…...

Unity——脚本序列化

在介绍序列化之前&#xff0c;我们先来了解一下为什么要对数据进行序列化 数据序列化有以下几个主要的应用场景和目的&#xff1a; 1. 持久化存储&#xff1a;序列化可以将对象或数据结构转换为字节序列&#xff0c;使得其可以被存储在磁盘上或数据库中。通过序列化&#xff…...

es(Elasticsearch)介绍

学习es可以参考mysql&#xff08;相比mysql而言&#xff0c;es所需的cpu、内存更多&#xff09; 什么是Elasticsearch Elasticsearch简称es&#xff0c;是由Elastic和search组成。Elastic的意思是有弹性的&#xff0c;search的意思是搜索。 弹性&#xff1a;es是一个天生支持分…...

C++中使用 do…while 循环

C中使用 do…while 循环 在有些情况&#xff08;如程序清单 6.8 所示的情况&#xff09;下&#xff0c;您需要将代码放在循环中&#xff0c;并确保它们至少执行一次。此时 do…while 循环可派上用场。 do…while 循环的语法如下&#xff1a; do {StatementBlock; // executed…...

开源vue动态表单组件

一、项目简介 vueelement的动态表单组件&#xff0c;拖拽组件到面板即可实现一个表单 二、实现功能 支持拖拽 支持输入框 支持文本框 支持数字输入框 支持下拉选择器 支持多选框 支持日期控件 支持开关 支持动态表格 支持上传图片 支持上传文件 支持标签 支持ht…...

怎么从0到1创建一个PHP框架-1?

写在前面 本人开发的框架在2021年年初开发完成&#xff0c;后面没有再做过任何维护和修改。是仅供大家参考交流的学习项目&#xff0c;请勿使用在生产环境&#xff0c;也勿用作商业用途。 框架地址&#xff1a; https://github.com/yijiebaiyi/fast_framework 整体思路 开发…...

Qt无边框青绿色主题

收费产品&#xff0c;学生党、闹眼子党勿扰 收费金额&#xff1a;500元 1 概述 最近因项目需要&#xff0c;写了一个炫酷的青绿色、无边框界面&#xff0c;和3DSMax的界面有点类似。 2 截图 首先看看3DSMax的界面 不知道大家看出来没&#xff0c;这个ui其实很简单&#xff…...

200 套基于Java开发的Java毕业设计实战项目(含源码+说明文档)

文章目录 简介前言第一部分第二部分部分截图源码咨询 简介 博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 前言 对于java方向的毕业设计题目选题&#xf…...

Ansible学习笔记7

user模块&#xff1a; user模块用于管理用户账户和用户属性。 如果是windows要换一个win_user模块。 创建用户&#xff1a;present&#xff1a; [rootlocalhost ~]# ansible group1 -m user -a "nameaaa statepresent" 192.168.17.106 | CHANGED > {"ansi…...

Python3 对列表、字典以及二者的嵌套数据(JSON)格式排序

在 Python 中&#xff0c;列表和字典都是基础数据类型&#xff0c;这两种数据类型会通过相互嵌套和多个层级形成复杂的数据类型&#xff0c;类似 JSON 数据格式&#xff0c;对列表和字典排序其实可以类比是对 JSON 排序。 列表排序 列表可以使用 sorted() 函数排序&#xff1…...

如何在B站进行学习直播

诸神缄默不语-个人CSDN博文目录 会根据我使用的情况进行持续更新 文章目录 1. 电脑 - 哔哩哔哩直播姬1. 软件的基础使用2. 素材1. 摄像头2. 窗口捕捉3. 游戏进程图片文字浏览器多媒体 3. H5插件其他注意事项 2. 手机直播3. iPad直播 1. 电脑 - 哔哩哔哩直播姬 1. 软件的基础使…...

老卫带你学---windows上安装minikube

老卫带你学—windows上安装minikube 1. 下载minikube https://storage.googleapis.com/minikube/releases/latest/minikube-installer.exe2.安装好后&#xff0c;将对应的目录添加env path 3. minikube start --kubernetes-versionv1.23.8 --image-mirror-countrycn...

Neo-reGeorg隧道搭建

目录 Neo-regeorg前言 环境搭建 具体使用 kail安装Neo-reGeorg kail内生成webshell并设置密码 kail与win10连接 windows server内打开服务 kail虚拟机访问windows server以及所在的内网 Neo-regeorg前言 regeorg为reDuh的升级版&#xff0c;主要功能就是把内网服务器的…...

Elasticsearch 7.6 - API高阶操作篇

ES 7.6 - API高阶操作篇 分片和副本索引别名添加别名查询所有别名删除别名使用别名代替索引操作代替插入代替查询 场景实操 滚动索引索引模板创建索引模板查看模板删除模板 场景实操一把索引的生命周期数据迁移APIGEO(地理)API索引准备矩形查询圆形查询多边形查询 自定义分词器…...

软件第三方验收测评介绍

软件第三方验收测试 软件项目验收测试介绍&#xff1a; 软件项目验收测试是部署软件之前的最后一个测试操作&#xff0c;是对系统进行全面的测试&#xff0c;以验证其是否符合合同要求&#xff0c;出具第三方测试报告&#xff0c;为系统验收提供依据。 验收测试的目的是&…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

沙箱虚拟化技术虚拟机容器之间的关系详解

问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西&#xff0c;但是如果把三者放在一起&#xff0c;它们之间到底什么关系&#xff1f;又有什么联系呢&#xff1f;我不是很明白&#xff01;&#xff01;&#xff01; 就比如说&#xff1a; 沙箱&#…...

SQL进阶之旅 Day 22:批处理与游标优化

【SQL进阶之旅 Day 22】批处理与游标优化 文章简述&#xff08;300字左右&#xff09; 在数据库开发中&#xff0c;面对大量数据的处理任务时&#xff0c;单条SQL语句往往无法满足性能需求。本篇文章聚焦“批处理与游标优化”&#xff0c;深入探讨如何通过批量操作和游标技术提…...