重量级锁、自旋锁、自适应自旋锁、轻量级锁、偏向锁、可重入锁、互斥锁/排他锁/独占锁

news/2024/6/29 12:01:40 标签:

重量级

获取不到就立刻进入阻塞状态的是重量级

轻量级

当另一个线程参与到偏向竞争时,会先判断 markword 中保存的线程 ID 是否与这个线程 ID 相等,如果不相等,会立即撤销偏向,升级为轻量级每个线程在自己的线程栈中生成一个 LockRecord ( LR ),然后每个线程通过 CAS (自旋 )的操作将对象头中的 markwork 设置为指向自己的 LR 的指针,哪个线程设置成功,就意味着获得 关于 synchronized 中此时执行的 CAS 操作是通过HotSpot 中 bytecodeInterpreter.cpp 文件 C++ 代码实现的。

如果真的遇到了竞争,我们就会认为轻量级已经不适合了,我们就会把轻量级升级为重量级了。

所以轻量级适合用在那种,很少出现多个线程竞争一个的情况,也就是说,适合那种多个线程总是错开时间来获取的情况。

自旋

自旋是JDK1.4.2的时候引入的, 默认为关闭状态, 可以使用-XX:+UseSpinning参数来开启 ,可以用-XX:PreBlockSpin 来控制自旋多少次, 默认是10次。

自适应自旋

JDK 6中对自旋的优化,引入了自适应的自旋。

自适应意味着自旋的时间不再是固定的了,而是由前一次在同一个上的自旋时间及的拥有者的状态来决定的。

如果在同一个对象上,自旋等待刚刚成功获得过,并且持有的线程正在运行中,那么虚拟机就会认为这次自旋也很有可能再次成功,进而允许自旋等待持续相对更长次数。

另一方面,如果对于某个,自旋很少成功获得过,那么自旋次数少,以避免浪费处理器资源。

有了自适应自旋,随着程序运行时间的增长及性能监控信息的不断完善,虚拟机对程序的状况预测就会越来越精准,虚拟机就会变得越来越“聪明”了。

偏向

偏向退出时不改变对象头中是偏向的标记,也不删除记录的线程ID,什么操作都没有,直接退出。

偏向升级:https://blog.csdn.net/haoranhaoshi/article/details/108530134

JDK1.8偏向默认不开启。开启方式:-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0。关闭方式:-XX:-UseBiasedLocking。

开启偏向后,如果执行监视对象的hashCode()方法后导致对象头种不能存储线程ID,就会升级。

偏向适用于那种,始终只有一个线程在执行一个方法的情况。

可重入

synchronized 拥有强制原子性的内部机制,是一把可重入。因此,在一个线程使用 synchronized 方法时调用该对象另一个 synchronized 方法,即一个线程得到一个对象后再次请求该对象,是永远可以拿到的。在 Java 中线程获得对象的操作是以线程为单位的,而不是以调用为单位的。synchronized 的对象头的 markwork 中会记录该的线程持有者和计数器,当一个线程请求成功后, JVM 会记下持有的线程,并将计数器计为1。此时其他线程请求该,则必须等待。而该持有的线程如果再次请求这个,就可以再次拿到这个,同时计数器会递增。当线程退出一个 synchronized 方法/块时,计数器会递减,如果计数器为 0 则释放该

互斥/排他/独占

synchronized 是一把互斥/排他/独占,当前线程如果获取到,会导致其他线程无法获取到

总结

偏向、轻量级、重量级的差异在于线程获取不到的策略:

偏向会升级为轻量级,轻量级会自旋或自适应自旋,重量级会使线程阻塞。

自旋、自适应自旋关注的是获取不到时不阻塞,不升级的策略。不关注加的是偏向、轻量级还是重量级


http://www.niftyadmin.cn/n/752454.html

相关文章

Centos配置任务计划

一、测试环境: 系统版本:Centos8.2 二、crontab简介: 查看crontab说明: [rootDA-Python ~]# cat /etc/crontab SHELL/bin/bash PATH/sbin:/bin:/usr/sbin:/usr/bin MAILTOroot# For details see man 4 crontabs# Example of …

为什么要前后端分离?有什么优缺点

一、前戏 前后端分离已成为互联网项目开发的业界标准使用方式,通过nginxtomcat的方式(也可以中间加一个nodejs)有效的进行解耦,并且前后端分离会为以后的大型分布式架构、弹性计算架构、微服务架构、多端化服务(多种客…

Centos 8.2 修改镜像源

Centos 8.2 修改镜像源 备份镜像源配置文件: cd /etc/yum.repos.d cp CentOS-Base.repo CentOS-Base.repo.bak cp CentOS-AppStream.repo CentOS-AppStream.repo.bak cp CentOS-Extras.repo CentOS-Extras.repo.bak修改镜像源配置文件: sed -i s|mirr…

[转]localhost、127.0.0.1和0.0.0.0和本机IP的区别

一、IP地址是什么 首先,我们要知道网络中的相互访问其实就是在进行两者间的数据传递。就如同送快递一样,快递发出只有知道你的住址信息,才能将快递送到你的手中。而在网络访问时,只有知道你在网络中的地址信息,才能将数…

Centos 8.2 安装配置Python3.6

Centos 8.2 安装配置Python3.6 一、测试环境: 系统版别:Centos8.2 Python版本:3.6 Oracle客户端:12 远程工具:Xshell 二、Centos升级: Centos修改镜像源 #请配置好网络环境 #最好将镜像源设置为国内…

Delphi实现Windows的气泡提示样式

其实也不复杂,主要使用到shellAPI下的TNotifyIconData这个结构体: typedef struct _NOTIFYICONDATA { DWORD cbSize; //结构体的大小,以字节为单位 HWND hWnd; //窗口的句柄 UINT uID; //应用程序定义的…

Maven将依赖安装到本地仓库

想将二方库的依赖加入Maven本地仓库,或者三方库的下载使用阿里的Maven仓库,但里面的依赖版本不够高,不够新,可以将依赖安装到Maven的本地仓库,那么以后就可以直接读取了,无需关联指定本地依赖存储的位置。而…

[Bzoj3224][Tyvj1728] 普通平衡树(splay/无旋Treap)

题目链接&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id3224 平衡树入门题&#xff0c;学习学习。 splay(学习yyb巨佬) 1 #include<bits/stdc.h>2 using namespace std;3 typedef long long ll;4 const int maxn 500100;5 const int INF 1e9;6 inline…