JUC-locks锁

JUC-locks锁

  • 1、JUC-locks锁概述
  • 2、管程模型
  • 3、ReentrantLock可重入锁
    • 3.1 ReentrantLock源码
    • 3.2 Sync静态内部类
    • 3.3 NonfairSync非公平锁
    • 3.4 FairSync公平锁

如有侵权,请联系~
如有错误,也欢迎批评指正~

1、JUC-locks锁概述

java的并发包【JUC】下面就两个子包,一个是atomic原子包,另一个就是lock锁包。这个包下就提供了三种锁:ReentrantLock【可重入锁】、ReentrantReadWriteLock【可重入读写锁】、StampedLock【更轻量级的读写锁】。
这些锁的实现大部分都是基于AbstractQueuedSynchronizer【俗称的AQS,分两篇文章,防止难以消化】类实现的。

2、管程模型

管程模型是并发编程的万能钥匙,juc包下的锁以及阻塞队列几乎都是使用的管程模型实现的。当然管程模型【java选择】和信号量是【操作系统】等价的,这两个都是用来解决并发问题,以使用信号量实现管程,也可以使用管程实现信号量。
管程就是指管理共享变量,以及对共享变量的相关操作,对应于java中类的属性和方法。管程主要是三种模型:Hasen 模型、Hoare 模型和 MESA 模型,Java 使用的是 MESA 模型。
管程特点:

  • 封装性:管程将共享资源和操作这些资源的同步机制进行封装,共享变量只能被管程中的方法访问,外部过程不能访问。
  • 互斥访问:管程确保每次只有一个线程能够执行管程中的代码。当一个线程在管程中执行时,其他试图进入该管程的线程被阻塞,直到当前线程退出管程。
  • 条件变量:管程通常可以有一个或多个条件变量,用于线程间的条件同步。线程可以在管程内部等待某个条件成立(通过调用某个等待函数),同时释放锁,直到条件满足时得到通知。

管程模型的整体架构图:
在这里插入图片描述

3、ReentrantLock可重入锁

ReentrantLock可重入锁支持公平锁也支持非公平锁(具体实现可以查看各自的tryAcquire()方法),选择公平锁还是非公平锁根据创建该对象时候的参数。

ReentrantLock类内部有三个静态内部类Sync(NonfairSync和FairSync的基类)、NonfairSync(非公平锁)、FairSync(公平锁)
在看源码之前,看一下整体的架构图【根据上面的管程模型进行改动】:
在这里插入图片描述

3.1 ReentrantLock源码

public class ReentrantLock implements Lock, java.io.Serializable {private final Sync sync;// 在创建ReentrantLock对象的时候就指定是使用公平锁还是非公平锁。无参构造默认使用非公平锁。public ReentrantLock() {sync = new NonfairSync();}public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();}// 调用内部静态类,根据参数是公平锁还是非公平锁public void lock() {sync.lock();}// 不管这个锁是公平的还是非公平的,都是按照非公平锁的方式获取资源方法public boolean tryLock() {return sync.nonfairTryAcquire(1);}// 调用AQS类的tryAcquireNanos,如果等待时间比较久超过1000ns,就会让该线程进行阻塞。// 这个会根据锁是公平锁还是非公平锁来获取资源,不同于tryLock()public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout));}public void unlock() {sync.release(1);}
}

3.2 Sync静态内部类

abstract static class Sync extends AbstractQueuedSynchronizer {// 抽象方法,等待实现类NonfairSync和FairSync实现。该方法被ReentrantLock.Lock()调用abstract void lock();// 非公平锁获取资源。直接就获取资源,只看是不是有资源(资源被其他线程占用)final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {// 如果资源没线程占用,则cas直接占用,占用成功直接返回,设置占用资源的线程为当前线程if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current == getExclusiveOwnerThread()) {// 如果当前资源被占用,但是是被自己占用的,则可以继续占用【可重入】int nextc = c + acquires;if (nextc < 0) // overflowthrow new Error("Maximum lock count exceeded");setState(nextc);return true;}return false;}// 这个方法其实是AQS中的方法,lock.unlock()就会调用这个方法public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);  // 释放完资源唤醒队列线程return true;}return false;}// 释放资源,释放资源不需要循环,只有获取资源才会竞争才需要CAS+自旋。释放不需要竞争protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())// 释放资源,前提肯定是当前线程占用资源。如果资源没被当前线程占用,当前线程释放肯定有问题throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);  // 如果释放所有资源,把owner线程释放}setState(c);return free;}}

3.3 NonfairSync非公平锁

一句话概述:当一个线程想要获取资源的时候,先争取去获取资源state,如果没竞争到再老老实实去阻塞队列中排队。
那为什么阻塞队列中有等待线程,state资源还可能为空呢?
有可能上一个线程刚释放,阻塞线程还没来的急抢占。

static final class NonfairSync extends Sync {// 非公平锁在放入队列之前先判断是否可以获取到锁,如果能够获取到直接使用,否则加入阻塞队列final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);  }protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}

3.4 FairSync公平锁

一句话概述:当前线程获取锁资源的时候,抢占资源的条件是阻塞队列中没有等待线程。

static final class FairSync extends Sync {// 直接加入阻塞队列final void lock() {acquire(1);}// 公平锁在获取资源的时候会先判断当前线程在队列中是否还存在前面的节点,即只有当前节点为第一个节点的时候才可以获取资源protected final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {// 这里就体现了如果阻塞队列中有等待线程,即使当前资源空闲,也需要乖乖去排队。if (!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;}
}

通过上述发现公平锁和非公平锁最大的区别就是:

  • 不同点:公平锁即使当前资源空闲,只要阻塞队列中有线程等待就会乖乖去排队,而非公平锁则是只要资源闲着就去抢一下,抢不到再老老实实去阻塞队列排队。【公平锁像是一个懂得克制的乖孩子,非公平锁则是调皮捣蛋的小孩子,不管行不行,先抢他一下试试】
  • 相同点:
    • 非公平锁抢了一下没获取到资源,也需要去排队,只给你一次机会。
    • 公平锁和非公平锁调用tryLock()都是非公平锁实现,直接看资源能不能获取到。

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

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

相关文章

GEE 数据集——美国gNATSGO(网格化国家土壤调查地理数据库)完整覆盖了美国所有地区和岛屿领土的最佳可用土壤信息

目录 简介 代码 引用 网址推荐 知识星球 机器学习 gNATSGO&#xff08;网格化国家土壤调查地理数据库&#xff09; 简介 gNATSGO&#xff08;网格化国家土壤调查地理数据库&#xff09;数据库是一个综合数据库&#xff0c;完整覆盖了美国所有地区和岛屿领土的最佳可用土…

kettle开发-Day43-数据对比

前言&#xff1a; 随着数字化的深入&#xff0c;各种系统及烟囱的建立&#xff0c;各系统之间的架构和数据存储方式不同&#xff0c;导致做数据仓库或数据湖时发现&#xff0c;因自建的系统或者非标准化的系统经常存在物理删除而不是软删除。这就延伸出一个问题&#xff0c;经常…

哪款开放式耳机好用?5款实力出众的开放式耳机按头安利!

随着耳机市场日益火爆&#xff0c;许多品牌与款式不断涌现。但是&#xff0c;不少劣质产品在核心性能上缺乏专业优化&#xff0c;且选用低质材料&#xff0c;在音质还原度和佩戴舒适性等关键方面存在明显短板&#xff0c;导致性能欠佳&#xff0c;聆听体验不佳&#xff0c;还可…

Unity资源打包Addressable资源保存在项目中

怎么打包先看“Unity资源打包Addressable AA包” 其中遗留一个问题&#xff0c;下载下来的资源被保存在C盘中了&#xff0c;可不可以保存在项目中呢&#xff1f;可以。 新建了一个项目&#xff0c;路径与“Unity资源打包Addressable AA包”都不相同了 1.创建资源缓存路径 在…

矩阵的各种计算:乘法、逆矩阵、转置、行列式等——基于Excel实现

在Excel中,可以使用内置的函数和公式来实现矩阵的各种计算。以下是具体方法: 矩阵乘法: 使用MMULT函数。如图矩阵A在单元格范围A1:B2,矩阵B在单元格范围D1:E2,结果矩阵的左上角单元格为G1:选中结果矩阵的区域(如G1:H2)。输入公式:=MMULT(A1:B2, D1:E2)。按Ctrl+Shift…

[ComfyUI]Flux:繁荣生态魔盒已开启,6款LORA已来,更有MJ6写实动漫风景艺术迪士尼全套

今天&#xff0c;我们将向您介绍一款非常实用的工具——[ComfyUI]Flux。这是一款基于Stable Diffusion的AI绘画工具&#xff0c;旨在为您提供一键式生成图像的便捷体验。无论您是AI绘画的新手还是专业人士&#xff0c;这个工具都能为您带来极大的便利。 在这个教程中&#xff…

【设计模式】关联关系与依赖关系

UML 图将事物之间的联系分为 6 种&#xff1a;关联、依赖、聚合、组合、泛化、实现 我认为关联关系和依赖关系非常不好理解。 我们看下定义&#xff1a; 关联&#xff1a;表示一种拥有的关系。具有方向性。如果一个类单方向的访问另一个类&#xff0c;称为单向关联。如果两个类…

前端Cypress自动化测试全网详解

Cypress 自动化测试详解&#xff1a;从安装到实战 Cypress 是一个强大的端到端&#xff08;End-to-End, E2E&#xff09;功能测试框架&#xff0c;基于 Node.js 构建&#xff0c;支持本地浏览器直接模拟测试&#xff0c;并具有测试录屏功能&#xff0c;极大地方便了测试失败时的…

#渗透测试#SRC漏洞挖掘#云技术基础02之容器与云

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

Android 下内联汇编,Android Studio 汇编开发

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ 内联汇编 Android 内联汇编非常适用于 ARM 架构的性能优化和底层操作&#xff0c;通常用于加密、解密、特定指令优化等领域。 1. 基础语法 内联汇编在 C/C …

深入剖析【C++继承】:单一继承与多重继承的策略与实践,解锁代码复用和多态的编程精髓,迈向高级C++编程之旅

​​​​​​​ &#x1f31f;个人主页&#xff1a;落叶 &#x1f31f;当前专栏: C专栏 目录 继承的概念及定义 继承的概念 继承定义 定义格式 继承基类成员访问⽅式的变化 继承类模板 基类和派⽣类间的转换 继承中的作⽤域 隐藏规则 成员函数的隐藏 考察继承【作⽤…

RHCE的学习(16)(shell脚本编程)

第一章、shell入门基础 1.1 为什么学习和使用Shell编程 对于一个合格的系统管理员来说&#xff0c;学习和掌握Shell编程是非常重要的。通过编程&#xff0c;可以在很大程度上简化日常的维护工作&#xff0c;使得管理员从简单的重复劳动中解脱出来。 Shell程序的特点&#xff…

信号量和线程池

1.信号量 POSIX信号量&#xff0c;用与同步操作&#xff0c;达到无冲突的访问共享资源目的&#xff0c;POSIX信号量可以用于线程间同步 初始化信号量 #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); sem&#xff1a;指向sem_t类…

docker运行ActiveMQ-Artemis

前言 artemis跟以前的ActiveMQ不是一个产品&#xff0c;原ActiveMQ改为ActiveMQ Classic, 现在的artemis是新开发的&#xff0c;和原来不兼容&#xff0c;全称&#xff1a;ActiveMQ Artemis 本位仅介绍单机简单部署使用&#xff0c;仅用于学习和本地测试使用 官网&#xff1a;…

区块链技术在电子政务中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 区块链技术在电子政务中的应用 引言 区块链技术概述 定义与原理 发…

【AI换装整合包及教程】CatVTON与其他虚拟试衣技术的详细对比

一、概述 虚拟试衣技术近年来发展迅猛&#xff0c;尤其在电商领域的应用备受瞩目。CatVTON作为一种新兴的虚拟试衣技术&#xff0c;凭借其轻量化设计和高效训练策略脱颖而出。本文将从网络结构、训练策略、推理过程及应用场景四个方面详细对比CatVTON与其他主流虚拟试衣技术。…

图论基本术语

图论算法 —— 图论概述-CSDN博客 理论基础 —— 图_依附于顶点v是什么意思-CSDN博客 理论基础 —— 图 —— 图的存储结构_十字链表和链式前向星-CSDN博客 语雀版本 概括&#xff1a;图是计算机中常用的一种存储结构&#xff0c;图论是数学的一个分支&#xff0c;他以图为…

ffmpeg内存模型

文章目录 展示图拷贝packet 重要&#xff01;&#xff01;&#xff01;avpacket.c相关函数av_packet_alloc 简单的赋值 里面的还有没有进行初始化的指针av_packet_ref 展示图 拷贝packet 拷贝packet有两种情况 1&#xff1a; 两个packet的buf引用的是同一个数据缓冲空间&#…

NCC前端调用查询弹框

系统自带的查询模板 弹框 调启使用默认的 查询模板 是在 单据模板的 列表模板中&#xff0c;有个查询区域 &#xff0c;查询区域就是查询模板内容如果在列表页做客开 新增按钮 调启查询模板 无问题&#xff0c;但是目前需求是需要再卡片页面下调启系统标准的调启模板代码 //调…

Python用CEEMDAN-LSTM-VMD金融股价数据预测及SVR、AR、HAR对比可视化

全文链接&#xff1a;https://tecdat.cn/?p38224 分析师&#xff1a;Duqiao Han 股票市场是一个复杂的非线性系统&#xff0c;股价受到许多经济和社会因素的影响。因此&#xff0c;传统的线性或近线性预测模型很难有效、准确地预测股票指数的价格趋势。众所周知&#xff0c;深…