Monitor概念介绍

一、Java对象头

HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

HotSpot虚拟机的对象头包括三部分信息:

  • Mark Word
  • 指向类的指针
  • 数组长度

普通对象

以 32 位虚拟机为例

Klass Word:指向对象的类型(一个指针找到它的类对象)

image-20230403210208174

一个int 类型占4个字节,而一个Integer对象占8 + 4个字节

数组对象

image-20230403210220449

说明

Object的对象头,分为两部分

  • 第一部分是Mark Word,用来存储对象的运行时数据比如:hashcode,GC分代年龄,锁状态,持有锁信息,偏向锁的thread ID等等。

    在64位的虚拟机中,Mark Word是64bits,如果是在32位的虚拟机中Mark Word是32bits

  • 第二部分就是Klass Word,Klass Word是一个类型指针,指向class的元数据,JVM通过Klass Word来判断该对象是哪个class的实例。

Mark Word结构

  • 32位虚拟机下:MarkWord有4个字节 最后2个bit位表示状态

image-20230403210236910

说明

age:垃圾回收时的分代年龄

biased_lock:是否为偏向锁

01/00(biased_lock后一位):加锁状态

Normal:对象正常状态

当对对象进行相应改变,如施加轻量级锁、重量级锁,GC时,相应的Mark Word Structure会发生改变

状态说明

状态 标志位 存储内容
未锁定 01 对象哈希码、对象分代年龄
轻量级锁定 00 指向锁记录的指针
膨胀(重量级锁定) 10 执行重量级锁定的指针
GC标记 11 空(不需要记录信息)
可偏向 01 偏向线程ID、偏向时间戳、对象分代年龄
  • 64位虚拟机下:MarkWord有8个字节 最后2个bit位表示状态

image-20230403210250034

二、Monitor概念

Monitor被翻译为监视器或管程(通常称为“锁”)

每个Java对象都可以关联一个Monitor对象(JVM提供),如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Word中就被设置指向Monitor对象的指针

Monitor结构

14.并发编程之Monitor概念介绍05.jpg

  • Monitor属性含义
    • Owner:锁的拥有者,唯一性,当线程尝试获得锁时若有其他线程引用,则无法获得
    • EntryList:阻塞(等待)队列,其他线程无法获得锁时,则一起进入阻塞队列,但是一旦线程释放锁,它们是竞争获得锁(而不是先来后到)
    • WaitSet:存放处于wait状态的线程队列,即调用wait()方法的线程

obj对象的MarkWord结构指向Monitor对象,当t2执行到synchronized方法时,首先判断临界区代码是否加锁。

t2首先判断Monitor Owner是否有线程引用,无则获得锁,执行临界区代码,其他线程t1,t3则进入阻塞队列,等待t2释放锁。

Monitor调用步骤

14.并发编程之Monitor概念介绍06.jpg

  • 刚开始MonitorOwnernull
  • 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-0Thread-1 是之前获得过锁,但条件不满足进入WAITING状态的线程,后面讲wait-notify时会分析

注意

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

Monitor概念介绍
http://example.com/2023/04/03/Monitor概念介绍/
作者
程序员小魏
发布于
2023年4月3日
许可协议