锁的介绍和分类(轻量级锁 重量级锁 偏向锁 自旋锁 互斥锁)

article/2025/8/19 3:11:20

目录

公平锁 非公平锁

非公平锁

公平锁

可重入锁 不可重入锁

可重入锁(递归锁)

不可重入锁

轻量级锁 重量级锁  偏向锁

重量级锁

自旋锁(循环上锁)

轻量级锁

轻量级锁的释放

偏向锁

自旋锁和互斥锁

自旋锁

互斥锁

为何要使用自旋锁

自旋锁可能潜在的问题

参考:


公平锁 非公平锁

非公平锁

非公平锁是抢占式的,有优先级区分的线程争夺锁。
包括:
synchronized关键字
ReentrantLock默认创建的也是非公平锁

公平锁

公平锁是先到先得的原则,排队获取。
new ReentrantLock(true)

可重入锁 不可重入锁

可重入锁(递归锁)

可重入锁也叫递归锁,指的是同步方法内调用加锁方法,只需要获取最外层锁即可畅通无阻,内部的其他锁不再需要获取,可直接访问。这种设计可以极大的减少锁控制(如果是可重入锁,只需要控制最外层的锁即可),避免锁控制混乱或释放不及时导致死锁发生的概率。

不可重入锁

只能进入一次,在同步方法内如果要获取同一把锁就会死锁。

轻量级锁 重量级锁  偏向锁

重量级锁

和monitor相关联属于重量级锁,因为有和操作系统的交互,会占用较多资源,所以有了轻量级锁和偏向锁。三者可以在对象的markword字段中后三位二进制数得到,01是正常状态和偏向锁状态,00是轻量级锁,10是重量级锁。

自旋锁(循环上锁)

重量级锁竞争的时候可以使用自旋来进行优化。

重量级锁会有阻塞,阻塞再唤醒就会有线程的上下文切换,效率较低。

于是在一个线程上锁时发现对象已经被占用,这时不会立马进入阻塞队列,而是会连续几次进行上锁的尝试。

这样会减少一些线程的阻塞,提升效率。自旋锁在单核cpu下没有意义,反而降低程序效率。

轻量级锁

轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。

如果没有锁膨胀,轻量级锁没有和操作系统的交互。

创建锁记录(Lock Record)对象,每个线程都的栈帧都会包含一个锁记录的结构,内部可以存储锁定对象的Mark Word 。

在进行锁定时,通过CAS(compare and swap)和该对象头中的mark word进行比较交换,如果成功了,那么此时 锁记录中就会存放对象头的mark word( hashcode epoch age等数据),对象的mark word就会被替换为一个64位的二进制数(末尾是00 表明是轻量级锁),表示该对象被某个线程锁了。

如果CAS不成功,就会进入锁重入或者锁膨胀(升级为重量级锁)

上锁过程,如果该线程的子方法里面还要加锁,那么就会发生锁重入,即再在前面的栈帧上方建立新的栈帧,里面同样维护着一个lock record内存,引用的对象依然时同一个,不过存放mark word 的地方存放null,因为不能进行CAS了。

锁膨胀就是当另一个线程想要CAS一个对象时,发现该对象已经被上锁,那么这时就会进入锁膨胀:

为该对象申请一个 monitor对象,然后第一个线程的栈帧中锁记录中的的object的地址就不是刚才的轻量级锁的标识了,就会指向monitor的地址,表明自己是一个重量级锁锁定的对象,同时后一个线程进入 entrylist,阻塞。

轻量级锁的释放

线程释放锁的时候如果CAS成功,那么说明没有发生锁膨胀,正常CAS设置锁对象的mark word即可。

线程释放锁的时候,CAS失败,就会进入重量级锁的解锁流程,即找到monitor对象,把owner设置为null,唤醒entrylist中的blocked线程。

这样的话就比重量级锁的开销更小,效率更高。

偏向锁

进一步优化轻量级锁(CAS导致效率变低),使用线程id来替换markword

而不是采用锁记录CAS markword。

每次只需要检查id是不是一个线程的即可。

自旋锁和互斥锁

多线程中,对共享资源进行访问,为了防止并发引发的相关问题,一般都是引入锁的机制来处理并发问题。java获取到资源的线程A对这个资源加锁,其余线程好比B要访问这个资源首先要得到锁,而此时A持有这个资源的锁,只有等待线程A逻辑执行完,释放锁,这个时候B才能获取到资源的锁进而获取到该资源。

这个过程当中,A一直持有着资源的锁,那么没有获取到锁的其余线程好比B怎么办?一般就会有两种方式:

1. 一种是没有得到锁的进程就直接进入阻塞(BLOCKING),这种就是互斥锁缓存

2. 另一种就是没有得到锁的进程,不进入阻塞,而是一直循环着,看是否可以等到A释放了资源的锁。

自旋锁

自旋锁(spin lock)是一种非阻塞锁,也就是说,若是某线程须要获取锁,但该锁已经被其余线程占用时,该线程不会被挂起,而是在不断的消耗CPU的时间,不停的试图获取锁。

互斥锁

互斥量(mutex)是阻塞锁,当某线程没法获取锁时,该线程会被直接挂起,该线程再也不消耗CPU时间,当其余线程释放锁后,操做系统会激活那个被挂起的线程,让其投入运行。

而《linux内核设计与实现》常常提到两种态,一种是内核态,一种是用户态,对于自旋锁来讲,自旋锁使线程处于用户态,而互斥锁须要从新分配,进入到内核态。这里你们对内核态和用户态有个初步的认知就好了,用户态比较轻,内核态比较重

为何要使用自旋锁

互斥锁有一个缺点,他的执行流程是这样的 托管代码  - 用户态代码 - 内核态代码、上下文切换开销与损耗,假如获取到资源锁的线程A立马处理完逻辑释放掉资源锁,若是是采起互斥的方式,那么线程B从没有获取锁到获取锁这个过程当中,就要用户态和内核态调度、上下文切换的开销和损耗。因此就有了自旋锁的模式,让线程B就在用户态循环等着,减小消耗。

自旋锁比较适用于锁使用者保持锁时间比较短的状况,这种状况下自旋锁的效率要远高于互斥锁。

自旋锁可能潜在的问题

过多占用CPU的资源,若是锁持有者线程A一直长时间的持有锁处理本身的逻辑,那么这个线程B就会一直循环等待过分占用cpu资源。

参考:

黑马 JUC

不可重入锁(自旋锁)带来的好处 - JavaShuo


http://chatgpt.dhexx.cn/article/7opRSd59.shtml

相关文章

最全锁种类

你可能听说过很多锁,也看到过很多文章讲解锁,这篇我在这里将对锁的不同分类进行描述锁的设计 互斥锁–共享锁 互斥锁:顾名思义,就是互斥的,意思就是当前同步代码块只能被一个线程访问,sync、reentrantlock、…

锁的类型有哪些

锁的类型有哪些 基于锁的属性分类:共享锁、排他锁。 基于锁的粒度分类:行级锁(INNODB)、表级锁(INNODB、MYISAM)、页级锁(BDB引擎 )、记录锁、间隙锁、临键锁。 基于锁的状态分类:意向共享锁、意向排它锁 共享锁(Share Lock) 共享锁又称读锁&…

Kettle使用教程之Job使用

1、Kettle的Job使用十分简单,这里也只是演示比较简单的操作,创建Job 2、点击转换,然后点击浏览,选择转换对象 3、执行按钮,运行该转换 4、如果需要长期的进行定时转换,可以在Job中的start控件进行配置 转载…

Kettle使用教程之数据同步

Kettle使用教程之数据同步 数据模型原型如下: 1、表输入,针对最新的数据输入的表 2、目标表,需要更新的表 3、两个表都需要进行排序操作 4、合并,根据id进行合并 5、数据同步(包括更新、插入、删除) 6、点击运行,就可…

ETL开发工具KETTLE使用教程

Kettle的建立数据库连接、使用kettle进行简单的全量对比插入更新:kettle会自动对比用户设置的对比字段,若目标表不存在该字段,则新插入该条记录。若存在,则更新。 Kettle简介:Kettle是一款国外开源的ETL工具&#xff0…

ETL工具Kettle使用教程

Kettle使用教程之数据同步 数据同步标识字段 标志字段的值有4种,分别是: “Identical” : 关键字段在新旧数据源中都存在,且域值相同 “changed” : 关键字段在新旧数据源中都存在,但域值不同 “new” : 旧数据源中没有找到该…

Kettle使用教程(一)—— 在MacOS系统中安装 Kettle

Kettle使用教程(一)—— 在MacOS系统中安装 Kettle 一、环境准备二、下载并启动Kettle二、初始化资源库 一、环境准备 Kettle 9.2JDK 1.8 (安装指引)Mysql(安装指引) 二、下载并启动Kettle 首先到官网下…

Kettle使用教程(问题)

关于kettle的介绍此文不做介绍 笔者电脑环境 winoraclejdk1.8kettle7.1 1. 考虑到在在官网下载速度比较慢,在这里可以使用国内的镜像 国内镜像 2. 配置java环境 (1) kettle需要以来java环境,因为没有安装java环境的朋友请移步配置java环境&#xff…

R-P-Faster R-CNN day65 读论文:高分辨率遥感影像综合地理空间目标检测框架

An Efficient and Robust Integrated Geospatial Object Detection Framework for High Spatial Resolution Remote Sensing Imagery 1. Introduction3. Overview of the Proposed R-P-Faster R-CNN Framework3.1. 有效集成区域建议网络与目标检测Faster R-CNN框架3.1.2. RPN与…

多特征融合的高分辨率遥感图像海陆分离——刘思彤

论文阅读笔记 摘要 为解决目前大多数海陆分离方法仅利用单一特征对图像进行处理,从而导致误分割或存在大量孤立区域,造成后续处理工作难度大或无法开展的问题,提出一种联合灰度、梯度和纹理等多特征的海陆分离方法。针对不同的陆地类型选用…

从实现的技术手段细数:高分辨率遥感影像+人工智能的现在和未来

【转自】http://baijiahao.baidu.com/s?id1601901487917871613&wfrspider&forpc 人工智能不可阻挡地向各行业渗透。这一现象,恰巧撞上了“商业遥感卫星发射潮”。这似乎预示了某种潜流。此刻,从事卫星遥感影像解译和大数据提取的专业人士、科研…

高分辨率光学遥感影像舰船目标检测与识别算法研究(尹莹莹)

论文阅读笔记 摘要 本文主要研究海陆背景下的光学遥感图像舰船目标检测与识别技术,重点研究了海陆分离、舰船目标疑似区域检测技术与疑似区域目标识别技术。 海陆分离: 采用了OTSU与形态学相结合的方法实现海路区域初步划分;再以孤立区域内…

基于高分辨率影像的潍坊大棚遥感提取

1 背景 朋友,当你坐在经过潍坊的火车上的时候,是否被窗外的风景震惊过?那一望无际的大棚,像一片海洋,又像一片草原,连接天际,一眼望不到边。在卫星地图上,白茫茫一片,蔚为…

如何浏览与下载全球免费的地图高分辨率(亚米级)的遥感影像?

目录 一.引言 二、高分辨率的地图数据源简介 1.Google Earth影像 2.Esri World Image 3.天地图 4.必应地图 5.高德地图 三、浏览与下载该地图源 1.Google Earth影像浏览与下载​ 2.Esri World Image的浏览与下载 3.天地图瓦片地址浏览与下载 4.必应地图浏览与下载 …

学习笔记-基于全局和局部对比自监督学习的高分辨率遥感图像语义分割-day2

高分辨率遥感图像语义分割-day2 摘要一、引言二、方法2.1 对比学习2.2 全局风格与局部匹配对比学习网络(GLCNet)2.2.1 全局风格对比学习模块:2.2.2局部匹配对比学习: 三、实验和结果A. 数据说明B. 实验设置1 基线:2 评…

基于全局和局部对比自监督学习的高分辨率遥感图像语义分割day3 - 网络结构

基于全局和局部对比自监督学习的高分辨率遥感图像语义分割day3 - 网络结构 前言自监督学习部分语义分割细调部分总结 前言 想要学习一个网络,最重要的就是网络结构和损失函数,一个讲了网络是怎么学,一个讲了网络将会学成什么样(个…

paddlepaddle打比赛之高分辨率遥感影像建筑物变化检测

★★★ 本文源自AlStudio社区精品项目,【点击此处】查看更多精品内容 >>> 1 赛事背景 城市是人类生活、生产的主要场所,在社会经济活动中处于重要位置。经济发展、人口增长和城市化进程的加快导致了城市地区的急剧变化,准确及时地识…

论文笔记(一)NFANET:一种新的高分辨率遥感影像弱监督水体提取方法

NFANet: A Novel Method for Weakly Supervised Water Extraction from High-Resolution Remote Sensing Imagery NFANET:一种新的高分辨率遥感影像弱监督水体提取方法 作者:Ming Lu,Leyuan Fang,Muxing Li,Bob Zhang,Yi Zhang,Pedram Ghamisi 期刊&…

论文学习笔记:高分辨率遥感影像解译中的机器学习范式

来源:National Remote Sensing Bulletin 遥感学报 作者:周培诚、程塨、姚西文、韩军伟 1. 西北工业大学 深圳研究院 , 深圳 518057; 2. 西北工业大学 自动化学院 , 西安 710072 传统的高分辨率遥感影像解译通常采用人工目视解译方式,费…

matlab提取遥感图像的点DN值,一种高分辨率遥感图像去雾霾方法

4 实验验证与分析 实验对象为两颗国产亚米级高分辨率遥感卫星图像, 即GF-2和Superview-1图像。两颗卫星参数如表1所示。其中, GSD为地面采样距离, 即空间分辨率; PAN表示全色谱段; B1~B4表示4个不同波段; MS表示多光谱谱段。从表1中可知其谱段设置为典型的大气窗口, 可避免臭氧…