文档章节

JVM之锁与并发

扬花落尽丶
 扬花落尽丶
发布于 2017/08/29 00:17
字数 1026
阅读 27
收藏 3

什么是锁:

  锁是多线程软件开发的必要工具之一,它的基本作用是保护临界区资源不会被多个线程同时访问收到破坏,由于多个线程访问造成对象的数据不一致,那么系统运行将会得到错误的结果。通过锁,可以让多个线程排队,一个一个进入临界区访问目标对象,使目标对象的状态总是保持一致,这就是锁存在的价值。  

对象头和锁:

   每个对象都有一个对象头,用于保护对象的系统信息。对象头中有一个成为Mark Word的部分,它是实现锁的关键。Mark Word在32位系统为一个32位的数据,64位系统为一个64位的数据。用来存放对象的哈希值、对象年龄、锁的指针等信息。

 32位系统距离Mark Word

   Mark Word中前25bit表示对象的哈希值,4位比特表示对象的年龄,1位比特表示是否为偏向锁,2位表示锁的信息。

  是否为偏向锁 锁的信息
无锁状态 0 01
偏向锁 1 01
轻量级锁 0 00
重量级锁 0 10

轻量级锁和重量级锁可以从Mark Word的后两位看出,然而无锁状态和偏量锁需要根据倒数第三个数据进行判断。

  •  偏向锁:

偏向锁是JDK1.6提出的一种锁优化方式。其核心思想是,如果程序没有竞争,则取消之前已经取得锁的线程同步操作。也就是说,若某一锁被线程获取后,便进入偏向锁模式,当线程再次请求的时候进行了锁请求,则锁退出偏向模式。在JVM中使用-XX:+UseBiasedLocking可以设置启动偏向锁。

  (当使用代码测试时,需要使用参数-XX:BiasedLockingStartupDelay表示虚拟机在启动后,立即启动偏向锁。如果不设置参数,虚拟机会默认在启动4秒后,才启动偏向锁)

应用场景:偏向锁在少量竞争的情况下,对系统性能有一定的帮助。但是在锁竞争激烈的场合下没有太强的优化效果,因为大量的竞争会导致持有锁的线程不停的切换,锁也很难保持在偏向模式。此时,使用锁偏向不仅得不到性能的优化,反而有可能降低系统的性能。因此,在激烈竞争的场合,可以尝试使用-XX:-UseBiasedLocking参数禁用偏向锁。

  • 轻量级锁:

如果偏向锁失败,Java虚拟机会让线程申请轻量级锁。轻量级锁在虚拟机内部,使用一个称为BasicObjectLock对象在线程栈中,因此该指针必然指向持有该锁的线程空间。当需要判断某一线程是否持有该对象锁时,也只需简单的判断对象头的指针是否在当前线程的栈地址范围内即可。同时,BasicLock对象的displaced_header字段,备份了援对象的Mark Word内容。BasicObjectLock对象的obj字段则指向该对象。

首先,BasicLock通过set_displaced_head()方法备份了援对象的Mark Word。接着,使用CAS操作,尝试BasicLock的地址复制到对象头的Mark Word。如果复制成功,那么加锁成功,否则认为加锁失败,那么轻量级锁就有可能被膨胀为重量级锁。

  • 锁膨胀:

当轻量级失败,虚拟机就会使用重量级锁。

第一步是废弃前面的BasicLock备份的对象头信息。第二步则正式启动重量级锁。启动过程分为两部:首先通过inflate()方法进行锁膨胀,其目的是获得对象的ObjectMonitor;然后使用enter()尝试进入该锁。

在enter方法调用中,线程很可能会在操作系统层面被挂起。如果这样,线程间切换和调度的成本就会比较高。

© 著作权归作者所有

共有 人打赏支持
扬花落尽丶
粉丝 5
博文 38
码字总数 31280
作品 0
朝阳
程序员
私信 提问
Java 并发编程源码解析汇总篇

java并发编程,内存模型 java并发编程,volatile内存实现和原理 Java并发编程,并发基础 Java 并发编程,线程池(ThreadPoolExecutor)源码解析 Java并发编程,Executor 框架介绍 Java并发编...

郑加威
2018/12/23
0
0
读书笔记之《Java并发编程的艺术》-并发编程基础

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

Hi徐敏
2015/11/11
0
8
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

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

Hi徐敏
2015/11/11
0
1
【死磕Java并发】—– 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。 先来一个总览图: 【高清图,请关注“Java技术驿站”公众号,回复:脑...

chenssy
2018/07/22
0
0
15个顶级Java多线程面试题及回答

Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分。如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题。在投资银行业务中多...

LCZ777
2014/05/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

数据库篇多表操作

第1章 多表操作 实际开发中,一个项目通常需要很多张表才能完成。例如:一个商城项目就需要分类表(category)、商品表(products)、订单表(orders)等多张表。且这些表的数据之间存在一定的关系...

stars永恒
今天
2
0
nginx日志自动切割

1.日志配置(Nginx 日志) access.log----记录哪些用户,哪些页面以及用户浏览器,IP等访问信息;error.log------记录服务器错误的日志 #配置日志存储路径:location / {      a...

em_aaron
昨天
3
0
java 反射

基本概念 RTTI,即Run-Time Type Identification,运行时类型识别。RTTI能在运行时就能够自动识别每个编译时已知的类型。   要想理解反射的原理,首先要了解什么是类型信息。Java让我们在运...

细节探索者
昨天
2
0
推荐转载连接

https://www.cnblogs.com/ysocean/p/7409779.html#_label0

小橙子的曼曼
昨天
3
0
雷军亲自打造的套餐了解下:用多少付多少

12月28日消息,小米科技创始人兼CEO雷军微博表示,小米移动任我行套餐方案,原则上就是明明白白消费,用多少付多少,不用不花钱!上网、电话和短信都是一毛钱,上网0.1元/M,电话0.1元/分钟,...

linuxCool
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部