什么是Java中的公平锁?

2023-11-04


一直想分析下公平锁和非公平锁在Java中的实现。
公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得
非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待
----------------------------------------------------------------------------------------------------
首先Java中的ReentrantLock 默认的lock()方法采用的是非公平锁。
也就是不用考虑其他在排队的线程的感受,lock()的时候直接询问是否可以获取锁,而不用在队尾排队。

下面分析下公平锁的具体实现。
重点关注java.util.concurrent.locks.AbstractQueuedSynchronizer类
几乎所有locks包下的工具类锁都包含了该类的static子类,足以可见这个类在java并发锁工具类当中的地位。
这个类提供了对操作系统层面线程操作方法的封装调用,可以帮助并发设计者设计出很多优秀的API


ReentrantLock当中的lock()方法,是通过static 内部类sync来进行锁操作
public void lock() 
{
     sync.lock();
}
//定义成final型的成员变量,在构造方法中进行初始化 
private final Sync sync;
//无参数默认非公平锁
public ReentrantLock() 
{
    sync = new NonfairSync();
}
//根据参数初始化为公平锁或者非公平锁 
public ReentrantLock(boolean fair) 
{
    sync = fair ? new FairSync() : new NonfairSync();
}

-----------------------------------------明日再更--------------------------
11月11日更
介绍非公平锁
static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }

那么调用默认构造方法构建的ReentrantLock的lock()方法的时候,其实调用的是NonfairSync对象的lock()方法,
protected final boolean compareAndSetState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,
unsafe对象是通过compareAndSwapInt方法实现的CAS操作
/** 
* 比较obj的offset处内存位置中的值和期望的值,如果相同则更新。此更新是不可中断的。 
*  
* @param obj 需要更新的对象 
* @param offset obj中整型field的偏移量 
* @param expect 希望field中存在的值 
* @param update 如果期望值expect与field的当前值相同,设置filed的值为这个新值 
* @return 如果field的值被更改返回true 
*/  
public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);  


CAS操作有3个操作数,内存值M,预期值E,新值U,如果M==E,则将内存值修改为U,否则啥都不做。

于是通过上面的CAS操作,判断state变量的值,如果是0(表明该锁没有被线程占用),则可以设置state为1,占有该锁。
从这里我们就可以看到非公平锁的不公平性,后面我们会看到有一个队列的线程可能在等待该锁的释放,而新来的线程我们看到直接询问是否可以拿到锁。


https://www.zhihu.com/question/36964449/answer/71678967

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是Java中的公平锁? 的相关文章

随机推荐

  • 守护进程的编程规则

    要理解守护进程的编程规则必须先搞明白进程组 会话 组长进程等关系 1 进程组 每个进程除了有一个进程ID之外 还属于一个进程组 进程组是一个或者多个进程的集合 每个进程组都有一个组长进程 组长进程的标识是 其进程ID和进程组ID相等 2 会
  • 基于粒子群算法优化的DBN深度置信网络数据预测及其Matlab实现

    基于粒子群算法优化的DBN深度置信网络数据预测及其Matlab实现 深度置信网络 Deep Belief Network DBN 是一类具有多层结构的前向神经网络 它由多个受限制玻尔兹曼机 Restricted Boltzmann Mach
  • UART串口Shell软硬件模型分析总结

    文章目录 层次一 最底层逻辑配置交互 如何从Uart硬件读写单个字节数据 层次二 抽象串口软件模块交互 基于串口对接输入输出流 和 Printf适配 层次三 类似Shell封装抽象交互 基于串口交互命令行界面 命令解析 补全 修改 记录 c
  • df -h 详解和centos 磁盘清理 /dev/vda1系统盘满了

    df h 检查一台服务器磁盘使用空间 发现磁盘已经使用了100 思路是 1 cd usr 当然这里不一定是 usr目录 最好是cd到 根目录再执行下一步 2 du sh 看哪个目录占用空间大 3 重复前两步 根据实际情况删除或者移走 4 日
  • QT 之键盘事件( keyPressEvent)

    一 介绍 keyPressEvent是QWidget里面的函数 所以凡是继承自QWidget的类都可以通过实现这个函数来完成对按键事件的响应 要让当前的widget能够响应按键事件 最先需要做的事情是 调用 setFocusPolicy Q
  • Vue3动画路由转场

  • PWA及小程序在系统生态方面的支持对比

    PWA代表 渐进式网络应用 Progressive Web Application 它是一种结合了网页和移动应用程序功能的技术概念 PWA旨在提供类似于原生应用程序的用户体验 包括离线访问 推送通知 后台同步等功能 同时又具有网页的优势 如
  • JS new操作符具体做了什么?

    1 意义 在JavaScript中 new 操作符用于创建一个新的对象实例 具体来说 new 操作符会执行以下步骤 JavaScript中的new操作符是一个非常重要的操作符 它用于创建一个新的对象实例 2 实例化步骤 创建一个新的空对象
  • ctfweb入门(13-14)

    ctf show web13 进入题目是个文件上传的题目 尝试了一番文件上传漏洞利用的方法后 没有啥突破 可能有啥隐藏的目录 尝试源码泄露利用的方法 在输入upload php bak时成功下载下来源码 bak文件是备份文件 这里列举一下常
  • 华为机试HJ15 求int型正整数在内存中存储时1的个数

    HJ15 求int型正整数在内存中存储时1的个数 Python 题目 解题思路 代码 结果 代码优化 题目 解题思路 1 输入转整数 用Python的bin方法转为二进制 再按字符串逐个检查等于1 的个数 优化 代码 res 0 for c
  • Ubuntu各个版本下载和安装

    一 下载方式 推荐使用网易镜像站下载 官网下载速度太慢 在官网下载ubuntu 网址 https ubuntu com download desktop 在网易镜像站下载ubuntu 网址 http mirrors 163 com ubun
  • lambda表达式提示变量错误:Variable used in lambda expression should be final or effectively final

    今天在使用lambda表达式时 遇到一个问题 Variable used in lambda expression should be final or effectively final 代码如下 ClassName CyclicBarr
  • 关于Sensor和ISP,对输出图像做Crop和Downscale的注意事项

    01 背景 客户要求调试ov的一款分辨率为4608x2592的Sensor 但目前我司的Soc最大支持分辨率是4096x3456 所以目前能出的最大分辨率为4096x2592 11M 客户要求ISP要出两路视频流 11M 1080P 且不能
  • WPF Windows 设置无边框还能拖动,缩放

    1 窗体的介绍 标准窗口由两个重叠矩形组成 外部矩形是非工作区 通常称为chrome 它由操作系统的窗口管理器进行绘制和管理 窗口的非工作区是通过 WPF 实现的 其中包括大多数窗口所共有的窗口部分 包括以下各项 边框 标题栏 图标 最小化
  • Oracle PGA

    PGA ProgramGlobal Area 程序全局区 PGA是用户进程连接到数据库并创建一个对应的会话时 由ORACLE为服务器进程分配的专门用于当前用户会话的内存区 每个Oracle服务器进程都包含有属于自己的PGA 它只存储这个服务
  • 小程序中实现VR效果

    小程序中实现VR效果 最近的工作中有一个奇葩的需求 就是更根据房间场景图 打开摄像机或者上传图片来适配不同的背景图 类似于VR的效果 一开始百度搜索 发现小程序根本没有VR的插件 而小程序要实现VR需要使用web view 也就是使用网页的
  • Livox 设备时间同步

    Livox wiki时间同步教程 下面是PTP时间同步的方法 是相对容易的一种 笔记本因为有线网卡的问题大概率没法完成 最好选台式机 首先ifconfig确认一下网卡情况 通过下面的指令来检查网卡是否支持软件 硬件时间戳功能 本机有线网卡
  • ESP32-CAM监控摄像头

    在此项目中 我们将使用ESP32 CAM开发板构建IP监控摄像头 ESP32相机将托管一个视频流Web服务器 您可以使用网络中的任何设备对其进行访问 您可以将此视频流Web服务器与流行的家庭自动化平台 如Home Assistant或Nod
  • C++实现——卡特兰数列及其应用

    卡特兰数列的原理及其应用场景 令h 1 1 catalan数满足递归式 h n h 1 h n 1 h 2 h n 2 h n 1 h 1 其中n gt 2 该递推关系的解为 h n c 2n 2 n 1 n n 1 2 3 1 1 2 5
  • 什么是Java中的公平锁?

    一直想分析下公平锁和非公平锁在Java中的实现 公平锁 Fair 加锁前检查是否有排队等待的线程 优先排队等待的线程 先来先得非公平锁 Nonfair 加锁时不考虑排队等待问题 直接尝试获取锁 获取不到自动到队尾等待 首先Java中的Ree