the King of 锁

麻雀虽小,五脏俱全。

多线程情况下。

基本锁升级

默认的锁升级情况如下:

无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁

为什么要有锁升级?这是应对不同的并发场景的策略。因为 Java 设计团队通过研究后认为:大多数锁修饰的对象,生命周期中大多只有一个线程在竞争。在默认修饰了 synchronized 的情况下,如果资源竞争并不激烈,在一个线程访问该资源时,会从无锁升级到偏向锁。在 sychronized 的设计中,会记录对应的 owner ID 为对应的线程 ID,此时的 mark down 为 01 。

怎么实现锁升级呢?

当有其他的线程初步发起竞争时,该锁会实现升级,成为轻量级锁,在处理策略上,顾名思义,保证轻量级而不涉及到系统的内核态切换阻塞,以 CAS + 自旋的策略维持着。CAS 是保证原子性的策略,而自旋则是应对频繁的挂起和唤醒,我们假定:抢锁若干周期后,它能够获取到该资源;如果一直无法获取,保持自旋的话,就会让 CPU 资源空转消耗。设想大量的并发访问某个资源时,如果全部采用 CAS 自旋,会导致大量资源的浪费。另外,在动态配置上,有自旋周期的自适应策略。

如果线程自旋若干周期无法访问到,那么我们就可以认为该资源无法被获取,从而升级成重量级锁。重量级锁是基于操作系统原语 mutux 而构建的。也就是说,它是互斥的。在这种情况下,线程 B 在状态上会变成 blocked,进入阻塞队列。

如果线程 A 一直不释放锁呢?线程 B 不就永远访问不到了吗?那么这种情况就是设计的问题了。我们要检查内部的情况,是否发生了阻塞。

Sychronized 同步

AQS

抽象队列同步策略。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇