博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三分钟掌握synchronized锁升级过程
阅读量:2400 次
发布时间:2019-05-10

本文共 801 字,大约阅读时间需要 2 分钟。

synchronized锁有四种状态,无锁,偏向锁,轻量级锁,重量级锁

锁可以升级但不能降级,但是偏向锁状态可以被重置为无锁状态

jdk1.6之前都是重量级锁,大多数时候是不存在锁竞争的,如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入锁升级。

1、偏向锁

线程1获取锁对象时,会在java对象头和栈帧中记录偏向的锁的threadID

线程1获取该锁时,比较threadID是否一致 ------- 一致 -> 直接进入而无需使用CAS来加锁、解锁

线程2获取该锁时,比较threadID是否一致 ------- 不一致 -> 检查对象的threadID线程是否还存活

存活:代表该对象被多个线程竞争,于是升级成轻量级锁

不存活:将锁重置为无锁状态,锁头重新标记线程2为新的threadID

(如果线程1和线程2的执行时间刚好错开,那么锁只会在偏向锁之间切换而不会升级为轻量级锁,在使用synchronized的情况下避开了获取锁的成本,所以效率和无锁状态非常接近)

2020-12-01

上述删除线的结论存疑,使用ClassLayout.parseClass(A.class).toPrintable(a)打印对象锁状态测试后,发现只要有第二个线程去锁该对象,无论原线程是否存活,该对象锁都会升级成轻量级锁。
但网上的大部分结论好像都是如果原线程销毁则偏向锁进行重偏向,很困惑。

2、轻量级锁

对象被多个线程竞争时,锁由偏向锁升级为轻量级锁,轻量级锁采用自旋+CAS方式不断获取锁。

3、重量级锁

当线程的自旋次数过长依旧没获取到锁或多个锁竞争发生在自旋阶段时,为避免CPU无端耗费,锁由轻量级锁升级为重量级锁。

获取锁的同时会阻塞其他正在竞争该锁的线程,依赖对象内部的监视器(monitor)实现,monitor又依赖操作系统底层,需要从用户态切换到内核态,成本非常高。

转载地址:http://geiob.baihongyu.com/

你可能感兴趣的文章
proxy 相关问题集(转)
查看>>
Linux下NFS网络文件系统设定及管理(转)
查看>>
ORACLE常用傻瓜问题1000问(之十二)(转)
查看>>
已经装了最新的binutils,为什么grub还是不能用(转)
查看>>
网络管理员指南 -10.网络信息系统 -1>熟悉NIS(转)
查看>>
巧用打印口制作笔记本密码破解器(转)
查看>>
Oracle 8 的函数介绍(转)
查看>>
CVSClient/Server连接设置(转)
查看>>
hosts.equiv和.rhosts文件(转)
查看>>
Linux关机命令详解(转)
查看>>
cron的使用(转)
查看>>
javascript动态隐藏显示技术(转)
查看>>
硬盘主引导记录详解(转)
查看>>
安装J2SE 1.3.1 for Linux的方法(转)
查看>>
Apche日志系列(5):高级技术(转)
查看>>
谈谈数据从sql server数据库导入mysql数据库的体验(转)
查看>>
解读startx(转)
查看>>
RMAN配置DATAGUARD完整案例(主库基于ASM存储)
查看>>
Oracle分区表
查看>>
关联查询子查询效率简单比照
查看>>