当前位置: 首页 > 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;为系统验收提供依据。 验收测试的目的是&…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...

解决MybatisPlus使用Druid1.2.11连接池查询PG数据库报Merge sql error的一种办法

目录 前言 一、问题重现 1、环境说明 2、重现步骤 3、错误信息 二、关于LATERAL 1、Lateral作用场景 2、在四至场景中使用 三、问题解决之道 1、源码追踪 2、关闭sql合并 3、改写处理SQL 四、总结 前言 在博客&#xff1a;【写在创作纪念日】基于SpringBoot和PostG…...

VUE3 ref 和 useTemplateRef

使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...

本地部署drawDB结合内网穿透技术实现数据库远程管控方案

文章目录 前言1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 前言 在数字化浪潮席卷全球的背景下&#xff0c;数据治理能力正日益成为构建现代企业核心竞争力的关键因素。无论是全球500强企业的数据中枢系统&#xff0c;还是初创…...