sychronized工作原理和Java对象结构-多线程安全-并发编程(Java)

1、Java对象头

  • Java对象构成:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding),图示:在这里插入图片描述

  • 对象头:以32位虚拟机为例,Java对象头构成如下

    • 普通对象:

      Object Header(64 bits)
      Mark Word(32 bits)Klass Word(32 bits)
    • 数组对象:

    Object Header(96 bits)
    Mark Word(32 bits)Klass Word(32 bits)Array Length(32 bits)
  • Mark Word结构:

Mark Word(32 bits)State
hashcode:25age:4biased_lock:001Normal
thread:23epoch:2age:4biased_lock:101Biased
ptr_to_lock_record:3000LightWight Locked
ptr_to_heavyweight_monitor:3010HeavyWeight Locked
 11Marked for GC
  • hashcode:哈希码,只有第一次调用对象.hashcode()之后,才会赋值,默认00000000

  • age:分代年龄,

  • biased_lock:是否偏向

  • 01:正常或者偏向,00:轻量级锁,10:重量级锁,11:标记为可垃圾回收

  • thread:线程地址

  • epoch:时代、纪元

  • ptr_to_lock_record:锁记录地址

  • ptr_to_heavyweight_monitor:Monitor对象地址

  • 参考地址:

2、Monitor

Monitor翻译为管程或监视器。

每个Java对象都可以关联一个Monitor对象,如果使用synchronized给对象上锁(总量级)之后,改对象头的Mark Word中被设置为指向Monitor的指针。

加锁(重量级)示意图:

在这里插入图片描述

工作原理,以加锁(重量级锁)为例:

  • 初始的时候,Monitor的Owner 为null,表示没有线程占用改锁对象
  • 当线程Thread-1执行synchronized(Object)之时,Object对象会关联一个Monitor对象,通过Java对象头的Makr Word指向关联的Monitor对象。
  • 此时会将Moniotor对象的Owner置为指向Thread-1的指针,Monitor只能有一个Owner。
  • 在Thread-1上锁后,有后续的Thread-2,Thread-3执行synchronized,需要获取锁对象,发现Owner不为空,此时,这些线程会进入Monitor的EntryList队列。
  • 如果有线程对象执行了wait()方法,会进入WaitSet集合;除非通过同一对象的notify或者notifyAll方法唤醒,不然一直在改集合中等待。
  • 当线程Thread-1执行完同步代码块的时候,释放锁对象,即Monitor对象的Owner置为null,同时会唤醒在EntryList上阻塞的线程,竞争锁对象。

注意事项:

  • synchronized必须是进入同一个对象的monitor时才有上述效果。
  • 不加synchronized的对象不好关联监视器,不遵从以上规则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gaog2zh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值