Synchronized


Monitor

 

Monitor象被称管程或者监视。在Java中,一个例都会关联一个Monitor个Monitor象既可以与象一起销毁,也可以在线试图获锁时生成

 

个Monitor象被线程持有后,便定状Synchronized的基本原理就是能否Monitor的所有

 

monitor

  ObjectMonitor() {

    _header       = NULL;

    _count        = 0; //用于记录线的次数,成功取到后count会加1,锁时count1

    _waiters      = 0,

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

    _object       = NULL;  // 存Monitor

    _owner        = NULL;  // 持有当前线程的owner

    _WaitSet      = NULL;// wait状线程列表

    _WaitSetLock  = 0 ;

    _Responsible  = NULL ;

    _succ         = NULL ;

    _cxq          = NULL ;  // 向列表

    FreeNext      = NULL ;

    _EntryList    = NULL ;// 于等待block状线程列表

    _SpinFreq     = 0 ;

    _SpinClock    = 0 ;

    OwnerIsThread = 0 ;

    _previous_owner_tid = 0;

  }

 

放 作 权  井 离 开 同 步  EntrySet  待 进 入 集 合  线 程  线 程  Owner  对 象 操 作 权 持 有 者  建 等 方 法  放 操 作 权  Obj 巳 1  M onitor  Obj 巳 2  M onitor  但 还 ,  线 程  开 同  线 程  线 程  WaitSet  待 授 权 集 合  线 程  线 程  线 程  Notify/N  线 程  EntrySet  待 进 入 集 合  线 程  同 步 块  得 对 象  Owner  对 象 操 作 权 持 有 者  线 程  获 得 对 象 操 作 权  WaitSet  待 授 权 集 合

 

 对象头

 

的Mark Word中主要存象自身的,例如、GC分代年线程持有的、偏向线程ID

 

25bit  Ibit  2bit  锁 状 态  4bit  是 否 偏 向 锁  锁 标 志 位  23bit  2bit  对 象 的 hashcode  分 代 年 龄  无 锁 状 态  0  0 0 0 1 1  内 上 内 上 0 0 内 上  偏 向 锁  分 代 年 龄  线 程 id  Epoch  1  指 向 栈 中 锁 记 录 ( L 。 Ck Record) 的 指 针  轻 量 级 锁  指 向 重 量 级 锁 ( M 。 nit 。 r 对 象 ) 的 指 针  重 量 级 锁  GC 标 记

 

偏向锁时Mark Word存了偏向线程的ID;

当状态为轻级锁时Mark Word存了指向线中Lock Record的指

当状态为重量级锁时Mark Word存了指向堆中的Monitor象的指

 

 

 

偏向

偏向的核心思想是,如果一个线得了,那么锁偏向模式,此Mark Word的结构变为偏向锁结构,即将中Mark Word的标记位改1,并且在Mark Word中记录该线程的ID。

 

级锁

Mark Word中的部分字CAS更新指向线中的Lock Record,如果更新成功,则轻级锁获取成功_,记录锁态为轻级锁;否明已线得了级锁,目前生了锁竞争(不继续使用级锁),接下来膨胀为重量级锁

JVM会在当前线程的线辟一块单独的空,里面保存指向Mark Word的指,同Mark Word中保存指向片空的指。上述个保存操作都是CAS操作,如果保存成功,代表线到了同步锁,就把Mark Word中的锁标志位改成00,可以行同。如果保存失,表示抢锁

 

自旋

空循一般不会行太多次,可能是50个循或100循经过若干次循后,如果得到,就入同。如果不能,那就会将线程在操作系统层面挂起,即入到重量级锁

 

重量级锁

重量级锁过对象内部的monitor实现(上文的Monitor Object模式)

monitor的本是依于底操作系的MutexLock实现,操作系统实现线的切是通户态与内核的切完成的,而切成本

MutexLock最核心的理念就是尝试获.若可得到就占有.若不能,就入睡眠等待

 

 

 

其他概念

 

消除

JVM在编译时过对运行上下文的描述,去除不可能存在共享争的,通过这种方式消除,即除不必要的加操作,开销

 

将多次接在一起的加、解操作合并一次,将多个连续锁扩展成一个范围更大的

如果虚检测到有一系列串的同一个象加和解操作,就会将其合并成一次范围更大的加和解操作,即在第一次append方法时进行加,最后一次append方法束后行解