【Java并发】ReentrantLock的实现原理

news2024/10/5 3:30:56

文章目录

    • ReentrantLock是什么?
    • ReentrantLock底层源码:
    • ReentrantLock底层原理图解:(以NonfairSync举例)

ReentrantLock是什么?

synchronized关键字是一种隐式锁,即它的加锁与释放是自动的,无需我们关心。而ReentrantLock是一种显式锁,需要我们手动编写加锁和释放锁的代码。
相对于synchronized它具备以下特点:

  • 可中断
  • 可以设置超时时间
  • 可以设置公平锁
  • 支持多个条件变量
  • 与synchronized一样,都支持重入(同一线程

例如:手动枷锁和解锁
在这里插入图片描述

注意被ReentrantLock加锁区域必须用try代码块包裹,且释放锁需要在finally中来避免死锁。执行几次加锁,就需要几次释放锁。

ReentrantLock底层源码:

在这里插入图片描述
点进去ReentrantLock的源码可以看到:
在这里插入图片描述
在这里插入图片描述
ReentrantLock实现了Lock接口

public interface Lock {
    // 获取锁
    void lock();
    // 获取可中断锁,即在拿锁过程中可中断,synchronized是不可中断锁。
    void lockInterruptibly() throws InterruptedException;
    // 尝试获取锁,成功返回true,失败返回false
    boolean tryLock();
    // 在给定时间内尝试获取锁,成功返回true,失败返回false
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    // 释放锁
    void unlock();
    // 等待与唤醒机制
    Condition newCondition();
}

在Lock中定义了多个获取锁的方法,以及释放锁的方法。同时还有一个与等待与唤醒机制有关系的newCondition方法

继续往下看Sync类是继承了AQS类(抽象队列同步器)的
在这里插入图片描述

ReentrantLock底层原理图解:(以NonfairSync举例)

  • exclusiveOwnerThread 表示独占当前锁的线程
  • head与tail 分别表示了等待线程队列的头结点和尾结点;
  • state 表示同步的状态,为0时表示未加锁状态,而大于0时表示加锁状态

在这里插入图片描述

  1. 线程来抢锁后使用cas的方式修改state状态,修改状态成功为1,则让exclusiveOwnerThread属性指向当前线程,获取锁成功
  2. 假如修改状态失败,则会进入双向队列中等待,head指向双向队列头部,tail指向双向队列尾部
  3. 当exclusiveOwnerThread为null的时候,则会唤醒在双向队列中等待的线程公平锁则体现在按照先后顺序获取锁,非公平体现在不在排队的线程也可以抢锁

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

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

相关文章

Android 开发面试中,面试官最喜欢问那些问题?

作者:小谢 “你遇到过哪些高质量的Android面试?” [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Pc1xZw5-1691675604271)(//upload-images.jianshu.io/upload_images/24388310-aa3c732481d0749f.png?imageMogr2/auto-orie…

自动脱扣型绝缘靴(手套)耐压支架操作步骤

一、概述 KDJS-8Q自动脱扣型绝缘靴(手套)耐压支架是根据《DLT 976-2017 带电作业工具、装置和设备预防性试验规程》、《DLT 1476-2015电力安全工器具预防性试验规程》、《GBT 17622-2008带电作业用绝缘手套》、《CB21148 2020足部防护 安全鞋》等…

【java】java项目在idea中Build Project或Rebuild Project一直进行不完

问题场景 我项目进行重新构建的时候,项目构建到某一个位置就一直不动了 解决方法 1.清理idea缓存 2.加大idea的内存 File -> Setting

在 Delphi 的 TRichEdit 中插入图片并保存为html文件

当在 Delphi 中使用 TRichEdit 组件时,有时需要将图片插入到文本中。下面详细介绍了如何在 TRichEdit 中插入图片。 引言: TRichEdit 组件是 Delphi 中常用的文本编辑控件,它不仅可以显示文本内容,还可以插入图片,丰富…

springboot汽车租赁后台java出租客户管理jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 springboot汽车租赁后台 系统有1权限:管理…

SCI论文中字体和图片字体大小的要求

SCI论文中字体和图片字体大小的要求 文章目录 1. American Chemical Society(ACS)要求2. Nature要求 1. American Chemical Society(ACS)要求 https://www.zhihu.com/question/380612293?utm_id0 2. Nature要求

章节1:HTTP协议回顾

章节1:HTTP协议回顾 HTTP请求方式 get请求:我们通常用其发起查询。 post请求:我们用其来向服务器提交数据。 HTTP请求格式 第一行为请求行。 HTTP响应格式 HTTP特点 请求应答模式灵活可扩展可靠传输无状态 stateless

网神 SecGate 3600 防火墙任意文件上传漏洞复现(HW0day)

0x01 产品简介 网神SecGate3600下一代极速防火墙(NSG系列)是基于完全自主研发、经受市场检验的成熟稳定网神第三代SecOS操作系统 并且在专业防火墙、VPN、IPS的多年产品经验积累基础上精心研发的高性能下一代防火墙 专门为运营商、政府、军队、教育、大型…

推出 Elasticsearch 查询语言 (ES|QL)

作者:Costin Leau 我很高兴地宣布,经过大约一年的开发,Elasticsearch 查询语言 (ES|QL) 已准备好与世界共享,并已登陆 Elasticsearch 存储库。 ES|QL 是 Elasticsearch 原生的强大声明性语言,专为可组合性、表现力和速…

网络加速与文件传输软件:如何通过优化网络提升文件传输速度

在信息化社会,文件传输是人们生活和工作中必不可少的一个环节。但是,由于网络环境的多样性和传输过程中可能出现的各种问题,文件传输速度经常受到影响。因此,如何优化网络以提高文件传输速度成为了一个重要的课题。本文将探讨网络…

Mybatis-plus 异常:Not Found TableInfoCache

标题:Mybatis-plus 异常:Not Found TableInfoCache Mybatis-plus 是一个流行的基于 Mybatis 的增强工具包,可以极大地简化数据库操作。然而,在使用 Mybatis-plus 过程中,可能会遇到一些异常情况,其中之一就…

mysql基础之触发器的简单使用

1.建立学生信息表 -- 触发器 -- 建立学生信息表 create table s1(id int unsigned auto_increment,name varchar(30),score tinyint unsigned,dept varchar(50),primary key(id) );2.建立学生补考信息表 -- 建立学生补考信息表 create table s2 like s1;3.建立触发器&#xf…

【excel技巧】excel公式如何隐藏?

Excel文件中最重要的除了数据还有就是一些公式了,但是只要点击单元格,公式就能显示出来,如果不想别人看到公式应该如何设置呢?今天分享隐藏excel单元格数据的方法。 选中单元格,点击右键打开【设置单元格格式】&#x…

【Linux】云服务器自动化部署VuePress博客(Jenkins)

前言 博主此前是将博客部署在 Github Pages(基于 Github Action)和 Vercel 上的,但是这两种部署方式对于国内用户很不友好,访问速度堪忧。因此将博客迁移到自己的云服务器上,并且基于 Jenkins(一款开源持续…

最强自动化测试框架Playwright-(2)实用操作

元素定位 定位器是playwright自动等待和重试功能的核心部分。简而言之,定位器表示一种随时在页面上查找元素的方法。 Locators | Playwright Python 如下这些是推荐的 page.get_by_role() 按显式和隐式辅助功能属性进行定位。 page.get…

Dockerfile 语法梳理及介绍

1. FROM FROM参数:从什么基础镜像构建新的镜像。 举例 : FROM centos, FROM ubuntu, FROM hello-world 使用 centos 镜像作为基础镜像。 注意:尽量使用官方的镜像作为基础镜像, 为了安全起见。 2. LABEL LABEL参数:从上…

交流汽车充电桩也有大功率的,为什么市场还是想做直流的?

新能源汽车交流充电桩和直流充电桩的区别是什么? 交流汽车充电桩也有大功率的,为什么市场还是想做直流的? 交流充电桩和直流充电桩最本质的区别是充电时车载设备的参与程度。 交流充电桩就好比是一双筷子,它把食物送到嘴里&#…

Windows 编译CEF源码详细记录

背景 默认的CEF不支持音视频功能&#xff0c;需要下载源码将ffmpeg开关打开&#xff0c;再进行编译。 Linux编译参考&#xff1a; 《Linux CEF源码下载编译详细记录》 创建目录结构 code/automate/automate-git.py <-- CEF build scriptchromium_git/cef/ …

Vue数组变更方法和替换方法

一、可以引起UI界面变化 Vue 将被侦听的数组的变更方法进行了包裹&#xff0c;所以它们也将会触发视图更新。这些被包裹过的方法包括&#xff1a; push()pop()shift()unshift()splice()sort()reverse() 以上七个数组都会改变原数组&#xff0c;下面来分别讲解它们的区别&…

《C和指针》(6)指针

1、内存和地址 计算机的内存是由数以亿万计的位&#xff08;bit&#xff09;组成&#xff0c;每一个位可以容纳值0、1值。由于一个位所能表示的值的范围太有限&#xff0c;所以单独的位用处不大。通常许多为合成一组作为一个单位&#xff0c;这样就可以存储范围较大的值。下图…