文档章节

java并发机制的底层实现原理

getqiu
 getqiu
发布于 2016/12/06 22:05
字数 1123
阅读 21
收藏 1

[TOC]

volatile的应用

volatile定义与实现原理

如果一个字段被申明为volatile,Java线程内存模型确保所有的线程看到这个变量的值是一致的。

具体来讲volatile的两条实现原则:

  • 1.Lock前缀指令会引起处理器缓存回写到内存。

  • 2.一个处理器的缓存回写到内存会导致其它处理器的缓存无效。

synchronized的实现原理与应用

并发编程当中,大多数时候都认为它为重量级锁。但是JDK1.6之后对synchronized进行了各种优化,引入了偏向锁和轻量级锁。

Java对象头

synchronized用的锁是存在Java对象头里的。

|代表状态 |存储内容 |标志位 |

|-------------------|--------------------------------------------|-----------|

|未锁定 |对象hash码,对象分代年龄 |01 |

|轻量级锁定 | 指向锁记录的指针 |00 |

|膨胀(重量级锁定)| 指向重量级锁的指针 |10 |

| GC标记 | 空,不需要记录信息 |11 |

|可偏向 | 偏向线程ID,偏向时间戳,对象年龄|01 |

锁升级与对比

Java6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”,锁一共有4中状态:无锁状态,偏向锁,轻量级锁和重量级锁。这4中状态会随着竞争的情况逐渐升级。锁可以升级,但是不能降级。

偏向锁

大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入偏向锁。

偏向锁设置

当一个线程访问同步块并获取锁时,会在对象头栈帧中的锁记录里存储偏向的线程ID。

以后该线程进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需要简单的测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。如果测试成功表示线程已经获得锁。

如果测试失败:则需要再测试一下Mark Word中偏向锁的标识是否被设置称为了1(标识当前是偏向锁)

如果没有设置,则使用CAS竞争锁;如果设置了,则尝试使用CAS将对象头的偏向锁指针指向当前线程。

偏向锁的撤销

偏向锁使用了一种等到竞争出现才释放锁的机制。所以当其它线程尝试竞争偏向锁是,持有偏向锁的线程才会释放锁。

偏向锁的撤销,需要等待全局安全点(这个点上没有正在执行的字节码)。

首先暂停拥有偏向锁的线程,然后检查持有偏向锁的线程是否存活,如果线程任然活着,那么这个线程将继续执行,遍历偏向对象的锁记录、栈中的锁记录和对象头Mark Word,要么重新偏向于其它线程,要么恢复到无锁活着标记为不适合作为偏向锁。

关闭偏向锁

偏向锁在Java6以上是默认开启的,但是它在应用程序启动几秒以后才激活,如果必要可以使用JVM参数来关闭延迟:-XX:BiasedLockingStartupDelay=0,如果程序当中的线程通常情况下处于竞争状态,可以通过JVM参数关闭偏向锁-XX:UseBiasedLocking=false

轻量级锁

轻量级锁加锁

线程在执行同步块之前,JVM会首先在当前线程的栈帧中创建用于存储锁记录的空间,并且将对象头中的Mark Word赋值到锁记录中,官方称为Displace Mark Word。然后线程尝试使用CAS将对象头中的MarkWord替换为指向 锁记录的指针。如果成功,当前线程获得锁,如果失败,表示其它线程竞争锁,当前线程变尝试使用自旋来获取锁。

轻量级锁解锁

轻量级锁解锁时,会使用原子操作CAS操作将Displaced Mark Word替换会到对象头,如果成功表示没有竞争发生,如果失败,表示当前存在竞争,锁就会膨胀称为重量级锁。

原子操作的实现原理

原子操作(atomic operation)意思为:不可被中断的一个或一系列操作。

© 著作权归作者所有

共有 人打赏支持
getqiu
粉丝 2
博文 12
码字总数 11145
作品 0
朝阳
程序员
私信 提问
读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
8
BAT等公司必问的8道Java经典面试题,你都会了吗?

工作多年以及在面试中,我经常能体会到,有些面试者确实是认真努力工作,但坦白说表现出的能力水平却不足以通过面试,通常是两方面原因: 1、“知其然不知其所以然”。做了多年技术,开发了很...

java填坑路
01/06
0
0
跳槽时,这些Java面试题99%会被问到

我在 Oracle 已经工作了近 7 年,面试过从初级到非常资深的Java工程师,且由于 Java 组工作任务的特点,我非常注重面试者的计算机科学基础和编程语言的理解深度,可以不要求面试者非要精通 ...

Java小铺
2018/08/15
0
0
读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
1
【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___
2018/05/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mac 10.14 编译Android 8.1源码及刷入nexus 6p

环境准备 官网 描述得已经相当清楚了 ,这里稍微总结一下: 创建区分大小写的磁盘映像 mac系统默认是不区分大小写的,所以我们需要创建一个区分大小写的文件系统 hdiutil create -type SPARS...

猴亮屏
10分钟前
0
0
js获取url参数

function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); var url =decodeURI(decodeURI(window.location.search)); var r = url.substr(1).match(reg);//s......

ArlenXu
17分钟前
1
0
(转)Spring MVC的常用注解

@Controller(常用) 注解一个类表示控制器,Spring MVC会自动扫描标注了这个注解的类。 @RequestMapping(常用) 请求路径映射,可以标注类,也可以是方法,可以指定请求类型,默认不指定为...

政旭Arvin
23分钟前
0
0
Navicat使用教程:在Navicat Monitor for MySQL/MariaDB中配置实例

下载Navicat Monitor最新版本 Navicat Monitor 是一套安全、简单而且无代理的远程服务器监控工具。它具有强大的功能使你的监控发挥最大效用。受监控的服务器包括 MySQL、MariaDB 和 Percona ...

电池盒
26分钟前
0
0
sql根据日期查询,本周,本月,本年,今日相关统计

sql根据日期查询,本周,本月,本年,今日相关统计 昨天 select * from tb where datediff(day, 时间字段 ,getdate()) = 1 今天 select * from tb where datediff(day, 时间字段 ,getdate()) = ...

BraveLN
36分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部