Javasynchronized底层的实现原理_第1页
Javasynchronized底层的实现原理_第2页
Javasynchronized底层的实现原理_第3页
Javasynchronized底层的实现原理_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第Javasynchronized底层的实现原理目录监视器底层实现执行流程总结前言:

想了解synchronized是如何运行的?就要先搞清楚synchronized是如何实现?synchronized同步锁是通过JVM内置的Monitor监视器实现的,而监视器又是依赖操作系统的互斥锁Mutex实现的,那接下来我们先来了解一下监视器。

监视器

监视器是一个概念或者说是一个机制,它用来保障在任何时候,只有一个线程能够执行指定区域的代码。

一个监视器像是一个建筑,建筑里有一个特殊的房间,这个房间同一时刻只能被一个线程所占有。一个线程从进入该房间到离开该房间,可以全程独占该房间的所有数据。进入该建筑叫做进入监视器(enteringthemonitor),进入该房间叫做获得监视器(acquiringthemonitor),独自占有该房间叫做拥有监视器(owningthemonitor),离开该房间叫做释放监视器(releasingthemonitor),离开该建筑叫做退出监视器(exitingthemonitor)。

严格意义来说监视器和锁的概念是不同的,但很多地方也把二者相互指代。

底层实现

下面我们在代码中添加一个synchronized代码块,来观察一下它在字节码层面是如何实现的?

示例代码如下:

publicclassSynchronizedToMonitorExample{

publicstaticvoidmain(String[]args){

intcount=0;

synchronized(SynchronizedToMonitorExample.class){

for(inti=0;ii++){

count++;

System.out.println(count);

}

当我们将上述代码编译成字节码之后,得到的结果是这样的:

从上述结果我们可以看出,在main方法中多了一对monitorenter和monitorexit的指令,它们的含义是:

monitorenter:表示进入监视器。monitorexit:表示退出监视器。

由此可知synchronized是依赖Monitor监视器实现的。

执行流程

在Java中,synchronized是非公平锁,也是可以重入锁。所谓的非公平锁是指,线程获取锁的顺序不是按照访问的顺序先来先到的,而是由线程自己竞争,随机获取到锁。可重入锁指的是,一个线程获取到锁之后,可以重复得到该锁。这些内容是理解接下来内容的前置知识。在HotSpot虚拟机中,Monitor底层是由C++实现的,它的实现对象是ObjectMonitor,ObjectMonitor结构体的实现如下:

ObjectMonitor::ObjectMonitor(){

_header=NULL;

_count=0;

_waiters=0,

_recursions=0;//线程的重入次数

_object=NULL;

_owner=NULL;//标识拥有该monitor的线程

_WaitSet=NULL;//等待线程组成的双向循环链表,_WaitSet是第一个节点

_WaitSetLock=0;

_Responsible=NULL;

_succ=NULL;

_cxq=NULL;//多线程竞争锁进入时的单向链表

FreeNext=NULL;

_EntryList=NULL;//_owner从该双向循环链表中唤醒线程结点,_EntryList是第一个节点

_SpinFreq=0;

_SpinClock=0;

OwnerIsThread=0;

}

在以上代码中有几个关键的属性:

_count:记录该线程获取锁的次数(也就是前前后后,这个线程一共获取此锁多少次)。_recursions:锁的重入次数。_owner:TheOwner拥有者,是持有该ObjectMonitor(监视器)对象的线程;_EntryList:EntryList监控集合,存放的是处于阻塞状态的线程队列,在多线程下,竞争失败的线程会进入EntryList队列。_WaitSet:WaitSet待授权集合,存放的是处于wait状态的线程队列,当线程执行了wait()方法之后,会进入WaitSet队列。

监视器执行的流程如下:

线程通过CAS(对比并替换)尝试获取锁,如果获取成功,就将_owner字段设置为当前线程,说明当前线程已经持有锁,并将_recursions重入次数的属性+1。如果获取失败则先通过自旋CAS尝试获取锁,如果还是失败则将当前线程放入到EntryList监控队列(阻塞)。当拥有锁的线程执行了wait方法之后,线程释放锁,将owner变量恢复为null状态,同时将该线程放入WaitSet待授权队列中等待被唤醒。当调用notify方法时,随机唤醒WaitSet队列中的某一个线程,当调用notifyAll时唤醒所有的WaitSet中的线程尝试获取锁。线程执行完释放了锁之后,会唤醒EntryList中的所有线程尝试获取锁。

以上就是监视器的执行流程,执行流程如下图所示:

总结

synchronized同步锁是通过JVM内置的Monitor监视器实现的,而监视器又是依赖操作系统的互斥锁Mutex实现的。JVM监视器的执行流程是:线程先通过自旋CAS的方式尝试获取锁,如果获取失败就进入

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论