Synchronized升级过程

以下截图及相关信息,均来源于马士兵公开课中


锁升级的过程

锁升级过程图:

image.png
image.png

锁升级过程:

new - 偏向锁 - 轻量级锁 (无锁, 自旋锁,自适应自旋)- 重量级锁

synchronized优化的过程和markword息息相关;

用markword中最低的三位代表锁状态 其中1位是偏向锁位 两位是普通锁位

一、无锁态:

通过 new 关键字创建对象

二、偏向锁:

偏向锁由于有锁撤销的过程revoke,会消耗系统资源,所以,在锁争用特别激烈的时候,用偏向锁未必效率高。还不如直接使用轻量级锁。

升级过程:

当线程调用这个对象时,发现这个对象没有被任何线程使用,会把指向当前的线程的指针(JavaThread*),放到对象头 markword 中,用于标记。锁升级为偏向锁。下次线程再次调用发现还是本线程的指针,无需再次上锁,直接调用。

markwork 存储值:

上偏向锁,指的就是,把markword的线程ID改为自己线程ID的过程;偏向锁不可重偏向 批量偏向 批量撤销

markword 上记录当前线程指针,下次同一个线程加锁的时候,不需要争用,只需要判断线程指针是否同一个,所以,偏向锁,偏向加锁的第一个线程 。hashCode备份在线程栈上 线程销毁,锁降级为无锁

三、轻量级锁:

升级原因:

当多个线程调用时,如果使用偏向锁,就会造成偏向锁不断的进行锁撤销和锁升级的操作,效率较低。

升级过程:

如果有线程竞争,撤销偏向锁,升级轻量级锁。线程在自己的线程栈生成LockRecord ,用CAS去争用markword的LR的指针,指针指向哪个线程的LR,哪个线程就拥有锁

线程抢夺锁:

每个线程都有自己的线程栈,在自己的线程栈生成一个自己的对象【Lock Record】;看谁能把自己的 Lock Record 贴到对象上,谁就拥有这把锁。抢的过程,通过自旋(CAS) 的方式抢夺,读取对象中的 Lock Record,并且判断是否可以修改,在回写本线程的Lock Record 指针到对象时,判断是不是自己取的那个值。

markwork 存储值:

线程在自己的线程栈生成LockRecord ,用CAS操作将markword设置为指向自己这个线程的LR的指针。

四、重量级锁

升级原因:

当自旋线程过多,执行线程占用时间又长。自旋会消耗大量CPU资源。不如升级为重量级锁,进入等待队列(不消耗CPU)-XX:PreBlockSpin

升级策略:
  1. 有线程超过10次自旋, -XX:PreBlockSpin, 或者自旋线程数超过CPU核数的一半;

  2. 在1.6之后,加入自适应自旋 Adapative Self Spinning , JVM自己控制

升级过程:

升级重量级锁 -> 向操作系统申请资源,获得 Linux mutex【锁】。CPU从3级【用户态】-0级系统调用【内核态】,线程挂起,进入等待队列,等待操作系统的调度,然后映射到用户空间。

markwork 存储值:

指向互斥量(重量级锁mutex )的指针。


锁重入

sychronized是可重入锁

重入次数必须记录,因为要解锁几次必须得对应

偏向锁 自旋锁 -> 线程栈 -> LR + 1

重量级锁 -> ? ObjectMonitor字段上

问题:

为什么有自旋锁还需要重量级锁?

自旋是消耗CPU资源的,如果锁的时间长,或者自旋线程多,CPU会被大量消耗

重量级锁有等待队列,所有拿不到锁的进入等待队列,不需要消耗CPU资源

偏向锁是否一定比自旋锁效率高?

不一定,在明确知道会有多线程竞争的情况下,偏向锁肯定会涉及锁撤销,这时候直接使用自旋锁

JVM启动过程,会有很多线程竞争(明确),所以默认情况启动时不打开偏向锁,过一段儿时间再打开

批量重偏向与批量撤销渊源:

从偏向锁的加锁解锁过程中可看出,当只有一个线程反复进入同步块时,偏向锁带来的性能开销基本可以忽略,但是当有其他线程尝试获得锁时,就需要等到safe point时,再将偏向锁撤销为无锁状态或升级为轻量级,会消耗一定的性能,所以在多线程竞争频繁的情况下,偏向锁不仅不能提高性能,还会导致性能下降。于是,就有了批量重偏向与批量撤销的机制。

原理以class为单位,为每个class维护解决场景批量重偏向(bulk rebias)机制是为了解决:一个线程创建了大量对象并执行了初始的同步操作,后来另一个线程也来将这些对象作为锁对象进行操作,这样会导致大量的偏向锁撤销操作。批量撤销(bulk revoke)机制是为了解决:在明显多线程竞争剧烈的场景下使用偏向锁是不合适的。

一个偏向锁撤销计数器,每一次该class的对象发生偏向撤销操作时,该计数器+1,当这个值达到重偏向阈值(默认20)时,JVM就认为该class的偏向锁有问题,因此会进行批量重偏向。每个class对象会有一个对应的epoch字段,每个处于偏向锁状态对象的Mark Word中也有该字段,其初始值为创建该对象时class中的epoch的值。每次发生批量重偏向时,就将该值+1,同时遍历JVM中所有线程的栈,找到该class所有正处于加锁状态的偏向锁,将其epoch字段改为新值。下次获得锁时,发现当前对象的epoch值和class的epoch不相等,那就算当前已经偏向了其他线程,也不会执行撤销操作,而是直接通过CAS操作将其Mark Word的Thread Id 改成当前线程Id。当达到重偏向阈值后,假设该class计数器继续增长,当其达到批量撤销的阈值后(默认40),JVM就认为该class的使用场景存在多线程竞争,会标记该class为不可偏向,之后,对于该class的锁,直接走轻量级锁的逻辑。

小知识:

  • 整个程序的执行状态分为

    • 用户态,内核态。内核态是非常核心的跟内核、硬件打交道的操作只有它能执行。【比如往网卡、显卡上写数据。】
  • 分代年龄

    • 一个对象被垃圾回收器回收一次,年龄会+1 ,年龄到达一定程度,这个对象会从 “年轻代” 升级到 ”老年代“。分代年龄在 JVM 里面是可以通过参数控制的,分代年龄两种默认值,第一种模式 15 ,PS+PO回收器 ;第二种模式 6 ,使用 cms 回收器 。4 Bit最大值15。
  • synchronized

    • 重量级锁,需要向操作系统申请,操作系统的锁个数是一定的。
  • 偏向锁

    • 更偏向于第一个调用它的线程。

    • 默认开启,可以关闭。

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

推荐阅读更多精彩内容