关于synchronized原理二三事

synchronized的用法就不细讲了,相信没人不知道的,今天就来剖析一下原理,加强记忆

对象头

synchronized的同步都是基于对象的,而当前对象的锁信息都是存在于对象头当中,我看先来看一下其构成:


图1.png

其中MarkWord的详细内容如下:


图2.png

我们来简述一下锁标志位(具体):
01:未加锁或者已经加了偏向锁,由是否是偏向锁的标志位来决定,主要用来提升 “ 某个锁一直重复被某个线程持有 ” 的情况下的性能。

00:轻量级锁,其原理就是通过cas操作去尝试修改锁指针,指向某个线程的栈帧,主要用来提升 “ 某个锁被多个线程交替持有 ” 的情况下的性能。
10:重量级锁,当轻量级锁修改锁指针失败后,代表着有多个线程在争抢这把锁,这时候就会通过对象监视器去调度线程,保证这个锁下面只有一个线程在执行。

偏向锁

在一开始,锁对象的MarkWord锁标志位为01,但是是否是偏向锁的标志位为0,说明这个锁还未被别人持有且还没有偏向。某一个线程在这种情况下想持有锁,就要通过cas操作去改变线程ID那一栏为当前线程并把是否是偏向锁的标志位改为1:

  • 成功,则以后某一线程想获取这这把锁,只要对比MarkWord中记录的线程ID是不是当前线程就行了。如果是则执行代码,如果不是则看看是否是偏向锁的标志位为0(未偏向),在未偏向的情况下其他线程可以继续通过cas操作继续修改MarkWord中记录的线程ID,从而继续使用偏向锁;在已偏向的情况下说明有竞争,则升级为轻量级锁。
  • 失败,说明有竞争,则升级为轻量级锁。

轻量级锁

升级到轻量级锁的过程是酱紫的:
1.首先会在当前线程的栈帧中建立一块锁记录(Lock Record)的空间,会把MarkWord的内容复制一份到锁记录中。
2.然后Lock Record中有的owner指针指向MarkWord所在的锁对象。
3.修改MarkWord中指向栈中锁记录的指针(见图2的那片区域)。


图3.png

修改指针都是用的cas操作,成功修改指针后代表该线程已经持有该锁,把锁标志位改为00。失败,则会通过自旋操作尝试获取锁,如果超过自旋的阈值还是获取不到则升级为重量级锁。

可重入是怎么做到的呢?

每重入一次,Lock Record就会在栈中再申请一次,只不过新的Lock Record中的本来会复制过来的MarkWord为null,释放时,也是一层层去释放的,当释放到最后一层时(也就是该栈中最初的Lock Record),会把Lock Record中的MarkWord通过CAS操作替换回锁对象的MarkWord。


图4.png

重量级锁

升级为重量级锁后,所标志位变为10,且锁指针指向互斥量,互斥量就是依赖于对象监视器,而对象监视器有以下几部分构成:

  • Contention List(cxq):竞争队列,在自旋失败后,线程首先会被放到这里面来等待。
  • Entry List:锁资源被释放时,会选取少量线程放到这里面作为执行候选。
  • Wait Set:调用 wait 方法被阻塞的线程放到这里面。
  • OnDeck:当前在争夺锁资源的线程(最多一个)。
  • Owner:当前已得到锁资源的线程。
  • !Owner:当前释放锁的线程。
图5.png

1.线程首先通过自旋尝试获取锁,当获取不到锁时,会通过cas操作插入到Contention List的队尾。
2.当owner线程unlock是,会把Contention List中的线程移到Entry List。
3.从Entry List选一个线程进入OnDeck状态,把锁竞争权利交给他,当然他也有可能被还在自旋的线程拿到锁。
4.获取到锁,并且执行。
5.被wait等方法阻塞,该线程释放锁并转移到Wait Set中。
6.被notify等方法唤醒,重新放到Entry List中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 1. 概念引入 Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是...
    Java旅行者阅读 822评论 0 4
  • ObjectMonitor 在HotSpot中,Monitor采用ObjectMonitor实现。 Monitor...
    长远勿见阅读 1,765评论 1 6
  • 1术语: CAS:Compare and Swap,比较并设置。用于在硬件层面上提供原子性操作。在 Intel 处...
    kennethan阅读 724评论 0 2
  • 近半年痴迷游戏,工作态度不佳我是知道的。但,万事知易行难,总是下不了决心改变,总是一次次重蹈覆辙。果然人类历史教训...
    loftcat阅读 133评论 0 0
  • 零点的钟声敲打我的脊背 年轻的诗人还没有入睡 她捧着纪伯伦写给玛丽的情书 让发自灵魂的清泉涌出 无边的黑暗包裹着孤...
    若溪写诗阅读 222评论 0 5