文档章节

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

chenssy
07/22
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面试:投行的15个多线程和并发面试题

本文由ImportNew -一杯哈希不加盐 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,...

ImportNew
08/23
0
0
读书笔记之《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语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员的欢迎。大...

小饼干的梦
10/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

码云项目100,水一发

简单回顾一下: 早期构想最多的,是希望能将PHP一些类和编码分区做得更细,所以很多尝试。但不得不说,PHP的功能过于单一,是的,也许写C/C++扩展,可以解决问题,那我为什么不用C#或者Golan...

曾建凯
今天
3
0
Spring应用学习——AOP

1. AOP 1. AOP:即面向切面编程,采用横向抽取机制,取代了传统的继承体系的重复代码问题,如下图所示,性能监控、日志记录等代码围绕业务逻辑代码,而这部分代码是一个高度重复的代码,也就...

江左煤郎
今天
4
0
eclipse的版本

Eclipse各版本代号一览表 Eclipse的设计思想是:一切皆插件。Eclipse核心很小,其它所有功能都以插件的形式附加于Eclipse核心之上。 Eclipse基本内核包括:图形API(SWT/Jface),Java开发环...

mdoo
今天
3
0
SpringBoot源码:启动过程分析(一)

本文主要分析 SpringBoot 的启动过程。 SpringBoot的版本为:2.1.0 release,最新版本。 一.时序图 还是老套路,先把分析过程的时序图摆出来:时序图-SpringBoot2.10启动分析 二.源码分析 首...

Jacktanger
今天
6
0
小白带你认识netty(二)之netty服务端启动(上)

上一章 中的标准netty启动代码中,ServerBootstrap到底是如何启动的呢?这一章我们来瞅下。 server.group(bossGroup, workGroup);server.channel(NioServerSocketChannel.class).optio...

天空小小
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部