synchronized 与 monitor 的理解

Mark Word 参考表
在这里插入图片描述
假设存在三个线程:线程A(线程编号为 A)、线程B(线程编号为 B)、线程C(线程编号为 C)

1、线程A首次访问同步块时

  • 线程A进入synchronized 同步块时。线程A会通过CAS设置Mark Word的线程ID为自己的ID,如果成功, 则获取锁。
    Mark Word 为: A|Epoch|age|1|01
    当前为偏向锁。

2、线程A再次访问时

  • 线程A会判断Mark Word的线程ID是否为自己的ID,如果是,则不需要CAS了,直接执行代码块。

3、当线程B访问同步块时(线程A正在访问同步块中)

  • 线程B进入synchronized 同步块时。
  • 线程A会通过CAS设置Mark Word的线程ID为自己的ID
    如果失败,将升级锁为轻量级锁,暂停线程A,Mark Word的线程ID设置为null, 然后唤醒线程A

4、被唤醒的线程A和线程B在轻量级锁中竞争

  • 线程A和线程B分别在自己的栈空间中新建一块存储锁记录的空间,然后将锁对象的Mark Word信息复制到开辟的空间中,然后线程A和线程B进行CAS将对象中Mark Word中的锁记录指针指向锁开辟拷贝的空间。
  • 假如线程B竞争成功,则线程A进入自旋状态来修改对象中Mark Word中的锁记录指针指向锁开辟拷贝的空间。如果失败则进入重量级锁。

5、进入重量级锁。(锁无法降级)

 此处将会用到monitor对象!!!

monitor对象重要属性说明:

  • _owner:指向持有ObjectMonitor对象的线程

  • _WaitSet:存放处于wait状态的线程队列

  • _EntryList:存放处于等待锁block状态的线程队列

  • _recursions:锁的重入次数

  • _count:用来记录该线程获取锁的次数

    假如当前线程A、B、C同时访问同步块。假如A获取到锁,也就会将 monitor 对象中的 _owner 的值赋值为当前线程ID。B、
    C线程会进入EntryList中。count =1 , recursions=1。假如A线程第二次进入同步快,count = 2, recursions=2,当前线程退
    出时,count和recursions会减一,直到count=0, recursions=0时,说明线程A释放了monitor锁,然后会唤醒EntryList中的线
    程,EntryList线程会竞争monitor,竞争到了,和线程A的操作一致。

WaitSet 主要是存放在同步块中执行 wait 方法的线程。配合 EntryList 就是 对象 的 wait 和 notify(notifyAll) 的底层实现。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值