CreateArtTechnology
/ Blog
Login
最新文章
Java
语言相关
库相关
虚拟机相关
CreateArtTechnology
项目搭建
使用的工具
自研的工具
开源工具
ELK
ElasticSearch
Jenkins
Markdown
GraphQL
Arthas
生产工具
Linux
Nginx
VersionControl
Subversion
Git
Redis
Archiva
Maven
Zookeeper
Spring
SpringBoot
MySql
HBase
Cassandra
容器化
Docker
Kubernetes
服务容器化从零开始
未分类笔记
算法相关
概念相关
豆知识
机器学习
机器学习从零开始
Synchronized的实现和锁升级
12
2019-03-15 17:11:40
Java
语言相关
### synchronized锁 **加锁方式** Java中的加锁大致分为两种: 1. 通过synchronized关键字修饰 2. 通过Lock的实现类在代码逻辑中显示加锁,如ReentrantLock **锁的实现思路** 无论是通过synchronized关键字或是通过Lock加锁,其实现思路是一样的,是尽量保证无锁化。 因此加锁过程都是通过锁升级的策略,不到万不得已不会使用资源消耗高的方法。 **锁状态** 1. `偏向锁` 这是在必须加锁的情况下最理想的状态,如果只有单一线程在访问资源,那么频繁的每次加锁、解锁也是非常消耗资源的。 通俗描述是“在乐观情况下,避免每次都进行加锁解锁操作”。 在偏向锁状态时: - “加锁” 实际上是将自身线程信息写入目标对象头信息中,并设置状态为“偏向锁状态” - “解锁” 实际上并没有做任何事 - “尝试加锁” 实际上是检查目标对象头中的偏向锁拥有者是否是自己,如果是,那么说明没有其他线程修改,无需再次进行加锁操作 在理想状态下,没有其他线程竞争,那么只有第一次加锁才需要消耗额外资源,其他情况下也是几乎没有额外消耗。 2. `轻量级锁` 当产生资源竞争时,无可避免需要加锁。但是考虑到很多操作其实耗时非常低,没有获取锁的线程可能刚进入阻塞状态锁就释放了。频繁的切换线程上下文代价也是非常大,不如再尝试多等一下。 通俗描述是“不阻塞,再多等一会试试”。 Java通过循环CAS(Compare And Set)在很多地方实现了自旋等待,如AtomicLong。CAS是现代CPU原生支持的命令,可以保证操作的原子性,但在高并发情况下持续循环CAS操作会占用过多的CPU资源。 在理想状态下,操作量级轻且竞争不激烈时,每个线程只需要做少量自旋等待即可获得资源,可以节约大量的线程上下文切换消耗。 3. `重量级锁` 一旦出现资源竞争,就阻塞未获得锁的线程,显然到了这个状态已经是没有其他选择了。 通俗描述是“没抢到的干等着”。 ![](/img/pic/2019031517172061902_png_1081_402_253849) > 不同状态之间的比较 **锁升级(锁膨胀)** 很明显在不同的竞争情况下,策略是可以不一样的,可以尽量避免使用更重的策略。 synchronized锁由轻到重可以升级膨胀,但不会降级。 synchronized关键字的升级策略: 1. 没产生冲突时,使用偏向锁 2. 一旦产生冲突,升级为轻量级锁 3. 轻量级锁在循环CAS一定次数的情况下仍然没有获取锁,则升级为重量级锁 **synchronized锁的实现细节** - synchronized关键字需要传入一个对象,如某类的实例或类对象本身,并且将锁的状态等信息保存在该对象的头信息中 - 根据竞争状态,通过JVM的调整将该对象的锁升级 - 竞争时是非公平的 ### 参考资料 [Java并发——Synchronized关键字和锁升级,详细分析偏向锁和轻量级锁的升级 - CSDN博客](https://blog.csdn.net/tongdanping/article/details/79647337)
发布文章 101
文章被阅读 1817
最近修改
什么是“丝滑”的曲线
2021-12-08 15:19:20
高效空间数据索引R树及其批量加载方法STR简介
2021-09-29 20:33:37
关于分库分表的一些事儿
2021-06-25 11:51:25
获得诺奖的稳定匹配理论之TTC算法与GS算法
2021-03-14 23:04:48
算法小白的机器学习入门实践,从零到上线
2021-01-13 14:28:27
分站宗旨
一站式资料平台,减少重复检索,减少重复采坑。