ReentrantLock的公平锁机制如何实现的?(源码理解)

news/2025/1/15 12:26:32/

公平锁是指多个线程按照申请锁的顺序来获取锁,即线程会直接进入队列中排队,队列中的第一个线程才能获得锁。这种机制确保了线程获取锁的公平性,避免了“饥饿”现象,即等待时间过长的线程无法获取到锁的情况。

默认情况下,ReentrantLock是非公平的,这是因为非公平锁的效率通常要高于公平锁。在没有特殊需求的情况下,一般推荐使用非公平锁,因为它能提供更高的性能。

通过查看ReentrantLock的构造方法,我们会发现有两种

 ReentrantLock lock = new ReentrantLock();ReentrantLock lock = new ReentrantLock(true);

 默认调用是NonfairSync()方法创建这个锁

公平锁的实现是在tryAcquire中实现的

 方法通过Thread.currentThread()获取当前线程对象,并将其赋值给变量current。然后,调用getState()方法获取当前锁的状态值,将其赋值给变量c

 判断状态值c是否为0。如果为0,表示锁未被占用,执行了hasQueuedPredecessors()方法

 

这个方法是用于判断当前线程是否有前驱节点在等待队列中。

方法首先获取尾节点(tail)和头节点(head),然后通过比较这两个节点是否相等来判断队列是否为空。如果头节点不等于尾节点,说明队列中有元素。

接下来,方法获取头节点的下一个节点(s = h.next),并检查该节点是否为null或者该节点的线程不是当前线程(s.thread != Thread.currentThread())。如果满足这些条件之一,说明当前线程有前驱节点在等待队列中,返回true;否则,返回false。

如果返回false就会执行compareAndSetState()方法,将状态值从0修改为acquires,则表示成功获取锁。之后调用setExclusiveOwnerThread(current)方法将当前线程设置为独占锁的拥有者。

如果状态值c不为0,表示锁已被占用。此时,需要进一步判断当前线程是否是锁的拥有者:

  1. 如果当前线程是锁的拥有者(即current == getExclusiveOwnerThread()),则可以将状态值增加acquires,并更新锁的状态值。
  2. 如果增加后的状态值nextc小于0,表示超过了最大锁计数,抛出异常。
  3. 更新锁的状态值为nextc
  4. 返回true表示成功获取锁。

 


http://www.ppmy.cn/news/1342589.html

相关文章

【Docker】Docker Registry(镜像仓库)

文章目录 一、什么是 Docker Registry二、镜像仓库分类三、镜像仓库工作机制四、常用的镜像仓库五、常用命令镜像仓库命令镜像命令(部分)容器命令(部分) 六、docker镜像仓库实战综合实战一:搭建一个 nginx 服务综合实战二:Docker hub上创建自己私有仓库综…

西瓜书学习笔记——核化线性降维(公式推导+举例应用)

文章目录 算法介绍实验分析 算法介绍 核化线性降维是一种使用核方法(Kernel Methods)来进行降维的技术。在传统的线性降维方法中,例如主成分分析(PCA)和线性判别分析(LDA),数据被映…

phpMyAdmin 未授权Getshell

前言 做渗透测试的时候偶然发现,phpmyadmin少见的打法,以下就用靶场进行演示了。 0x01漏洞发现 环境搭建使用metasploitable2,可在网上搜索下载,搭建很简单这里不多说了。 发现phpmyadmin,如果这个时候无法登陆,且也…

记录首次使用yolov8-obb

1.数据格式 之前使用的数据格式是yolov5_obb的数据格式,然后需要转数据格式: 目前的数据只支持四个坐标点标注的数据,参考:If a corner of the rotate rectangle is out of the image range, How to annotate the image? Issu…

2024甲级测绘名单之:百度地图的那些事儿

之前,我们分享过2023高精地图甲级测绘资质最新名单【高德地图】,没看过的小伙伴可以戳下面的链接: 2023高精地图甲级测绘资质最新名单【高德地图】-CSDN博客 今天继续介绍名单中的另外一个成员,也是地图导航业务的佼佼者&#x…

Ansible自动化运维实战

一、abstract简介 ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric) 的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能.无客户端。我们要学一些Ansible的安装和一些基…

CSS的复合选择器

一,什么是复合选择器 常用的复合选择器有:后代选择器、子选择器、并集选择器和伪类选择器。 二,后代选择器(用空格)(重点) 后代选择器也称包含选择器,可以选择父元素里面的子元素。…

修改MFC图标

摘要:本文主要讲解了MFC程序窗口图标的添加、任务栏、底部托盘的图标添加,以及所生成的exe文件图标的添加。 ​​​​​​​1、在资源视图添加Icon资源 透明图标怎么制作? 1)点击图片》右键:使用画图3D进行编辑 2&a…