Java之Synchronized锁详解

Javat头对象

Java中对象在内存由两部分组成(对象头和和一些成员变量)。
对象头,包含 Mark Work 与 Klass Work 两个部分,在32位虚拟机中占64位,8字节。前四个字节叫 Mark Work,后四个字叫 Klass Work。数组对象的对象头还有额外的32位(8字节)代表数组长度。

  1. Klass Work
    对象确定类型靠 Klass Work 指针,其指向对象所属的类对象。

  2. MarkWork
    MarkWork结构如下:

  • hashcode:对象的哈希值。
  • age:垃圾回收用到的年龄。
  • biased_lock:是否是偏向锁。
  • 后两位:加锁状态。

注:在不同的加锁状态中,Mark Work 的结构也各不相同。
32位虚拟机 Mark Work 结构:

64位虚拟机 Mark Work 结构:

Monitor

每个 Java 对象都可以关联一个 Monitor 对象(操作系统提供),如果使用 synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向Monitor对象的指针。
对象的 MarkWork 初始值的后两位是01,代表未加锁。当对 Normal 状态的对象加锁时,就把后两位修改为10,代表加了重量级锁,前面的30位就修改为指向 monitor 对象的指针。

如图所示:

  • 刚开始 Monitor 中 Owner 为 null。
  • 当 Thread-2 执行 synchronized(obj) 就会将 Monitor 的所有者 Owner 置为 Thread-2,Monitor中只能有一个 Owner。
  • 在 Thread-2 上锁的过程中,如果 Thread-3,Thread-4,Thread-5 也来执行 synchronized(obj),就会进入EntryList BLOCKED状态。
  • Thread-2 执行完同步代码块的内容,然后唤醒 EntryList 中等待的线程来竞争锁,竞争的时是非公平的。
  • WaitSet 中的 Thread-0,Thread-1 是之前获得过锁,但条件不满足进入 WAITING 状态的线程。
posted @ 2020-08-14 18:03  金牌厨师小庄  阅读(316)  评论(0)    收藏  举报