java之ReentrantLock

在讲RentrantLock之前需要先讲一下AQS和LockSupport,因为rentrantLock底层是用AQS实现的,而AQS中获取阻塞和唤醒底使用LockSupport实现的。

1、LockSupport实现

下面代码中,LockSupport.park方法是当前线程等待,直到获得许可,LockSupport.unpark方法则将线程作为参数传递,释放许可,让myThread能继续运行。

    static class MyThread extends Thread {@Overridepublic void run() {System.out.println(Thread.currentThread() +": start park");LockSupport.park();System.out.println(Thread.currentThread() +": end park");}}public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();System.out.println(Thread.currentThread() +": start unpark");LockSupport.unpark(myThread);System.out.println(Thread.currentThread() +": end unpark");}

park和unpark方法类似于object默认的wait和notify,区别在于:

1、Object.wait需要在同步代码块中执行,而park则不需要

2、wait当中断时,则会响应中断抛出中断异常,park不需要

3、object.wait是对象才能调用,而park则任何线程中都能调用

正因为park和unpark是对线程的阻塞和唤醒。适合运用到 ReentrantLock的并发线程中,其他线程阻塞和唤醒中。

2、AQS

网上有很多讲解AQS机制的,都列出一大堆源码,这里都不在多说源码了,简单说一下基本原理,至于细节部分,可以直接看源码后细扣。AQS核心思想是:如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

2.1 AQS的数据结构

AQS底层数据结构是一个CLH的虚拟双向队列,实际上是一个双向链表,而请求共享需要等待的线程则会加入同步队列中,如果使用condition,则会加入到等待队列中,每一个线程使用以下图中Node节点表示。Node节点包含pre,next,当前线程,waitStatus。

其中waitStatus包含四种状态:

// CANCELLED,值为1,表示当前的线程被取消
static final int CANCELLED =  1;
// SIGNAL,值为-1,表示当前节点的后继节点包含的线程需要运行,也就是unpark 
static final int SIGNAL    = -1;
// CONDITION,值为-2,表示当前节点在等待condition,也就是在condition队列中
static final int CONDITION = -2;
// PROPAGATE,值为-3,表示当前场景下后续的acquireShared能够得以执行 
static final int PROPAGATE = -3;
值为0,表示当前节点在sync队列中,等待着获取锁

3、 ReentrantLock实现原理

知道了上述两个知识点之后,lock.lock和lock.unlock方法内部到底是怎么实现的呢?

    public static void main(String[] args) {Lock lock = new ReentrantLock();MyThread t1 = new MyThread("t1", lock);MyThread t2 = new MyThread("t2", lock);t1.start();t2.start();}static class MyThread extends Thread {private Lock lock;public MyThread(String name, Lock lock) {super(name);this.lock = lock;}@Overridepublic void run() {lock.lock();try {try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("thread ==== " + Thread.currentThread() + " running");} finally {lock.unlock();}}}

上述代码中t1 和t2同时执行,当t1执行lock之后,t2则等待lock释放锁,等到t1执行unlock之后,t2则被唤醒执行下面操作。内部具体流程是怎么样的?

1、当t1执行lock之后,由于此时只有t1这一个线程,则直接将此线程设置为独占锁

2、当t2执行lock之后, 由于t1已经是独占锁了。所以此时t2则需要加入到同步队列中

(1)先初始化同步队列,创建一个head节点,

(2)将head指向t2线程

(3)将head节点状态设置为SIGAL,当前节点的后继节点包含的线程需要运行,可以执行unpark

(4)对t2执行LockSupport.park(),阻塞t2线程

3、t1执行unlock,除了释放自身的独占锁之后,后续对同步队列中的t2线程也有相关操作

(1)从后往前找,找到状态设置为SIGAL的节点,是head节点,然后对后续节点执行unpark操作,上述我们知道unpark,则是唤醒t2线程

(2)将head节点状态设置为0

4、由于之前t2在lock过程中,底层AQS代码是一个自旋,不断获取资源,t2线程被唤醒执行后,将t2自身将清空,head指向t2, next为null;最终达到的状态是sync queue中只剩下了一个结点,并且该节点除了状态为0外,其余均为null。

5、t2执行unlock,最后的状态和之前的状态是一样的,队列中有一个空节点,头节点为尾节点均指向它。

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

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

相关文章

Istio-解决Zipkin对项目的侵入性问题

Istio采用SideCar模式注入的Enovy代理在某些情况下不能完全解决对项目的无侵入性,比如需要用到Istio的链路追踪功能的时候。需要在代码中手动注入链路追踪需要的header,这样就出现了Istio对业务功能的侵入性。 istio服务网格的调用链跟踪需要依赖在服务之…

大数据环境搭建(一)-Hive

1 hive介绍 由Facebook开源的,用于解决海量结构化日志的数据统计的项目 本质上是将HQL转化为MapReduce、Tez、Spark等程序 Hive表的数据是HDFS上的目录和文件 Hive元数据 metastore,包含Hive表的数据库、表名、列、分区、表类型、表所在目录等。 根据Hive部署模…

axios二次封装用法

axios二次封装 一、request.js import axios from axios import router from "/router";const request axios.create({baseURL: http://localhost:9090,timeout: 5000 })// request 拦截器 // 可以自请求发送前对请求做一些处理 // 比如统一加token,对…

什么是进销存?一文读懂进销存管理系统

阅读本文,你将了解:一、什么是进销存;二、什么是进销存管理系统;三、为什么有必要使用进销存管理系统;四、进销存管理系统的优势;五、好用的进销存管理系统。 这是我们公司搭建好的免费进销存系统模版&…

近屿智能引领行业前沿,精心打造AIGC大模型工程师和产品经理的进阶之路(附完整版学习路径图)

近屿智能,倾力打造了一套独特的AIGC大模型工程师和产品经理学习路径图。该路径图清晰地展示了从初学者到专家水平的技能进阶过程,为工程师和产品经理提供了明确的学习目标和成长路径。 这套学习路径图适用于不同背景和经验的学习者,无论您是初…

GPT在地学、GIS、气象、农业、生态、环境等领域中的高级应用

详情点击公众号:技术科研吧 链接:GPT在地学、GIS、气象、农业、生态、环境等领域中的高级应用 一开启大模型 1 开启大模型 1)大模型的发展历程与最新功能 2)大模型的强大功能与应用场景 3)国内外经典大模型(ChatGPT、LLaMA、Gemini、DAL…

Python创建类的成员并访问

在Python中,类是面向对象编程的核心概念之一。通过类的定义,可以创建对象并定义对象的属性和方法。本文将介绍在Python中如何创建类的成员(包括属性和方法),以及如何访问类的成员。 1. 创建类的属性 在Python…

【XR806开发板试用】TCP通信测试 Ping 命令测试

1.工程准备 由于要使用wifi功能,直接从wlan_demo复制一份出来,然后修改。 源文件只留下 main.c 就可以了。 BUILD.gn文件 import("//device/xradio/xr806/liteos_m/config.gni")static_library("app_mying") {configs []sources…

2024美赛C题完整解题教程及代码 网球运动的势头

2024 MCM Problem C: Momentum in Tennis (网球运动的势头) 注:在网球运动中,"势头"通常指的是比赛中因一系列事件(如连续得分)而形成的动力或趋势,这可能对比赛结果产生重要影响。球…

STL常用容器—list容器(链表)

STL常用容器—list容器(链表) 一、list容器基本概念二、list容器基本操作与常用方法1. list构造函数2. ☆list 插入和删除3. list 获取头尾数据4. list 大小操作5. list赋值和交换6. list 反转和排序 三、排序案例 参考博文1: <C>…

计算机视觉中的目标跟踪

从保护我们城市的监控系统到自动驾驶车辆在道路上行驶,目标跟踪已经成为计算机视觉中的一项基础技术。本文深入探讨了目标跟踪,探索了其基本原理、多样化的方法以及在现实世界中的应用。 什么是目标跟踪? 目标跟踪是深度学习在计算机视觉中广…

JAVA Web 学习(四)RabbitMQ、Zookeeper

十、消息队列服务器——RabbitMQ RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求…

ES6-let

一、基本语法 ES6 中的 let 关键字用于声明变量,并且具有块级作用域。 - 语法:let 标识符;let 标识符初始值; - 规则:1.不能重复声明let不允许在相同作用域内重复声明同一个变量2.不存在变量提升在同一作用域内,必须先声明才能试…

JS(react)图片压缩+图片上传

上传dome var fileNodeTakeStock: any createRef();<inputref{fileNodeTakeStock}onChange{showPictureTakeStock}style{{ display: "none" }}id"fileInpBtn"type"file"accept"image/*" //限制上传格式multiple{false}capture&qu…

RK Camera hal 图像处理

soc&#xff1a;RK3568 system:Android12 今天发现外接的USBCamera用Camera 2API打开显示颠倒&#xff0c;如果在APP 里使用Camera1处理这块接口较少&#xff0c;调整起来比较麻烦 RK Camera hal位置&#xff1a;hardware/interfaces/camera 核心的文件在&#xff1a; 开机…

深入理解Istio服务网格(一)数据平面Envoy

一、服务网格概述(service mesh) 在传统的微服务架构中&#xff0c;服务间的调用&#xff0c;业务代码需要考虑认证、熔断、服务发现等非业务能力&#xff0c;在某种程度上&#xff0c;表现出了一定的耦合性 服务网格追求高级别的服务流量治理能力&#xff0c;认证、熔断、服…

N-142基于springboot,vue停车场管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本项目分为普通用户和管理员…

基于若依的ruoyi-nbcio流程管理系统自定义业务回写状态的一种新方法(一)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

深度学习驱动下的自然语言处理进展及其应用前景

文章目录 每日一句正能量前言技术进步应用场景挑战与前景自然语言处理技术当前面临的挑战未来的发展趋势和前景 伦理和社会影响实践经验后记 每日一句正能量 一个人若想拥有聪明才智&#xff0c;便需要不断地学习积累。 前言 自然语言处理&#xff08;NLP&#xff09;是一项正…

FreeRTOS动态 / 静态创建和删除任务

本篇文章记录我学习FreeRTOS的动态 / 静态创建和删除任务的知识。希望我的分享能给你带来不一样的收获&#xff01;文中涉及FreeRTOS创建和删除任务的API函数&#xff0c;建议读者参考以下文章&#xff1a; FreeRTOS任务相关的API函数-CSDN博客 目录 ​编辑 一、FreeRTOS动态创…