转自http://www.cnblogs.com/redcreen/archive/2011/03/29/1998801.html

大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意。原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的。互斥是一种会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源的操作。

为了优化Java的Lock机制,从Java6开始引入了轻量级锁的概念。

轻量级锁(Lightweight Locking)本意是为了减少多线程进入互斥的几率,并不是要替代互斥。它利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救。

本文将详细介绍JVM如何利用CAS,实现轻量级锁。

原理详解

Java Object Model中定义,Object Header是一个2字(1 word = 4 byte)长度的存储区域。

第一个字长度的区域用来标记同步,GC以及hash code等,官方称之为 mark word。第二个字长度的区域是指向到对象的Class。

在2个word中,mark word是轻量级锁实现的关键。它的结构见下表

从表中可以看到,state为lightweight locked的那行即为轻量级锁标记。bitfieds名为指向lock record的指针,这里的lock record,其实是一块分配在线程堆栈上的空间区域。

用于CAS前,拷贝object上的mark word(为什么要拷贝,请看下文)。

第三项是重量级锁标记。后面的状态单词很有趣,inflated,译为膨胀,在这里意思其实是锁已升级到OS-level。

在本文的范围内,我们只关注第二和第三项即可。

为了能直观的理解lock,unlock与mark word之间的联系,我画了一张流程图:

在图中,提到了拷贝object mark word,由于脱离了原始mark word,官方将它冠以displaced前缀,即displaced mark word(置换标记字)。

这个displaced mark word是整个轻量级锁实现的关键,在CAS中的compare就需要用它作为条件。

为什么要拷贝mark word?其实很简单,原因是为了不想在lock与unlock这种底层操作上再加同步。

在拷贝完object mark word之后,JVM做了一步交换指针的操作,即流程中第一个橙色矩形框内容所述。

将object mark word里的轻量级锁指针指向lock record所在的stack指针,作用是让其他线程知道,该object monitor已被占用。

lock record里的owner指针指向object mark word的作用是为了在接下里的运行过程中,识别哪个对象被锁住了。

下图直观地描述了交换指针的操作。

最后一步unlock中,我们发现,JVM同样使用了CAS来验证object mark word在持有锁到释放锁之间,有无被其他线程访问。

如果其他线程在持有锁这段时间里,尝试获取过锁,则可能自身被挂起,而mark word的重量级锁指针也会被相应修改。

此时,unlock后就需要唤醒被挂起的线程。

java代码轻量级锁_Java轻量级锁原理详解(Lightweight Locking)相关推荐

  1. Java 轻量级锁原理详解(Lightweight Locking)

    2019独角兽企业重金招聘Python工程师标准>>> 大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意. 原因是,monitorenter与mo ...

  2. java代码逻辑讲解_java逻辑控制语句实例详解

    一.Java选择结构 1.if(条件)-else结构 当条件==true时执行if下的语句,否则执行else下的语句 2.if(条件1)-else if(条件2)-else结构(相关视频教程推荐:ja ...

  3. java虚拟机工作原理_Java虚拟机工作原理详解

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入: javac YourClassNa ...

  4. java单例设计模式_Java设计模式之单例模式详解

    在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...

  5. java connection 单例_Java设计模式之单例模式详解

    Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...

  6. java解析json数据_java解析JSON数据详解

    JSON是目前最流行的轻量级数据交换语言(没有之一).尽管他是javaScript的一个子集.但由于其是独立与语言的文本格式,它几乎可以被所有编程语言所支持. 以下是对java语言中解析json数据的 ...

  7. java的static类_java中staticclass静态类详解

    一般情况下是不可以用static修饰类的.如果一定要用static修饰类的话,通常static修饰的是匿名内部类. 在一个类中创建另外一个类,叫做成员内部类.这个成员内部类可以静态的(利用static ...

  8. java指数表示法_Java指数计数法详解

    Java指数计数法详解 时间:2017-10-16     来源:华清远见Java培训中心 Java指数计数法并不是一个很难的运算,关键是你要理解应用,很多朋友不理解Java指数计数法,所以也无从运用 ...

  9. java调用oracle存储过程_java调用oracle存储过程详解

    之前给大家介绍了java代码调用存储过程,下面要给大家介绍的就是java当中调用oracle存储过程,一起来看看吧. 首先来看一下项目结构: 在数据库创建存储过程的脚本,假如,使用的是本地的oracl ...

最新文章

  1. JSONObject JSONArray各种用法以及js eval()函数与JSON.parse的区
  2. tableau必知必会之通过 Tableau 计算挖掘数据真相
  3. 【算法入门】用Python手写五大经典排序算法,看完这篇终于懂了!
  4. python实现选择文件_用tkinter 实现从文件夹选择文件并显示
  5. Idea 我的快捷键总结
  6. 2.Linux 高性能服务器编程 --- IP 协议详解
  7. android圆图,Android实现圆形图片或者圆角图片
  8. WSL:vi 的使用、只读下的修改操作
  9. 同一个项目的同一DLL多版本的兼容问题
  10. Spring Hibernate Validation
  11. CSP - 201403-1 - 相反数 (C++)
  12. 用showdown预览markdown文件(vue3.0)
  13. JAVA生成纯色背景图-自定义大小-自定义颜色
  14. I Squared Capital投资AGP City Gas
  15. OpenCV玩微信小游戏星途WeGoing
  16. 【随机过程】第二版龚光鲁译课后习题4.5参考答案
  17. 【网盘项目日志】Seafile 源码部署和安装命令
  18. 嘿嘿 抢到了iphone4
  19. FOURCC四字符码列表
  20. Silverlight实用窍门系列:14.Visifire图表控件的使用一(图表的创建和基础使用)【附带源码实例】...

热门文章

  1. wxWidgets:wxString概述
  2. wxWidgets:事件和事件处理
  3. boost::system::error_condition相关的测试程序
  4. boost::process:std_out相关的测试程序
  5. boost::hana::lift用法的测试程序
  6. boost::graph模块实现深度优先搜索 和广度优先搜索算法的测试程序
  7. boost::format模块演示添加到 printf 语法的功能
  8. Boost.Flyweight 复合设计示例
  9. boost::detail::lowest_bit的测试程序
  10. Boost:使用静态c ++内核语言扩展以进行编译和 执行模板化的c ++内核