大家知道,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后就需要唤醒被挂起的线程。
版权声明:本文为博主原创文章,未经博主允许不得转载。
转自 :http://blog.csdn.net/songylwq/article/details/5585734
相关推荐
轻量级人体姿态估计lightweight-human-pose-estimation.rar
基于JAVA的轻量级ORM框架(A lightweight ORM framework for JAVA)。
DrJava is a lightweight development environment for writing Java programs. It is designed primarily for students, providing an intuitive interface and the ability to interactively evaluate Java code. ...
This project is based on Java, is a lightweight ORM model. Only concerned about the Object-Relationl Mapping, therefore more simple and easier to use, easier to control. Key support functions and ...
RFC1777 轻量级目录访问协议 (RFC1777 Lightweight Directory Access Protocol) 本备忘录状态 This memo provides information for the Internet community. It does not specify an Internet standard of any ...
musicg is a lightweight audio analysis library, written in Java, with the purpose of extracting both high level and low level audio features. This API allows developers to extract audio features and ...
基于分布式配置中心配置限流参数的Redis轻量级分布式限流组件-lightweight-rate-limiter
由于这些设备是高度资源受限的,与传统的加密方法相比,使用更少的功率、更少的内存和更少的计算的轻量级加密算法是首选。 本文从门面积、吞吐量、效率、内存和算法复杂度等参数分析了硬件体系结构中的各种对称密码...
LongUI 0.2.2 轻量级C ++ GUI库LongUI中的功能重量轻LongUI的主要目标静态链接框架,helloworld bin文件大小小于200kb 为此,LongUI中没有c ++异常XML用户界面语言与Mozilla的XUL部分兼容(XML部分) 部分兼容CSS...
跨平台的最轻量级socket的c++库,支持windows,linux,solaris-cross-platform of the most lightweight c socket library, support for Windows, Linux, Solaris
LDAP的基本概念LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写,是一种基于 客户机/服务器模式的目录服务访问协议.其实是一话号码簿,LDAP是一种特殊的数据库。LDAP目录的优势LDAP协议是跨...
OkSocket is a Java library project designed to solve lightweight Socket communication, in order to enable developers to focus more on business logic, rather than TCP communication principles and some ...
python web 轻量级框架 web.py基本教程.
Android-Java-8-Stream-Example, 演示应用使用 Retrolambda 8特性和和轻量级流 API Android Java流API示例使用 Java 8功能和 Retrolambda 和 Lightweight-Stream-API的演示应用。功能:( )> lambda表达式...
4种常用Java线程锁的特点,性能比较、使用场景 ...在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。
无线网络以及各种智能设备的兴起,使得移动支付越来越重要,因此必须采用安全的轻量级移动支付协议(Lightweight Mobile Payment Protocol,LMPP)来保障移动支付的顺利进行。针对资源有限的移动设备及环境受限的...
轻量级密码学在过去几年中非常重要。 它成为安全嵌入式系统中最重要的模块之一,因为它一直是任何资源受限设备的强烈要求,并且具有几个特性,例如,它只消耗更少的功率、更少的内存等。本文是对各种轻量级设备的...
GenHTTP Web服务器GenHTTP是用纯C#编写的轻量级Web服务器,对第三方库的依赖性很小。 该项目的主要目的是为.NET编写的小型Web应用程序和Web服务提供服务,使开发人员可以专注于功能而不是处理基础结构。 例如,该...
A Lightweight Chinese Natural Language Processing Toolkit,提供中文分词, 中文词性标注, 文本纠错,文本转拼音,情感分析...
【超分辨率】小米轻量级超分辨率模型FALSR:Fast, Accurate and Lightweight Super-Resolution models-附件资源