一、对象头

对象由对象头Object Header和对象体Object Body组成
32位虚拟机中,对象头有64位,对象头包括4字节的Mark Word和4字节的Kclass Word
Kclass Word:指明该对象的类型
Mark Word:偏置锁、轻量级锁等信息
image.png

二、Monitor原理/重量级锁原理

Monitor(锁)

Monitor被翻译为:监视器管程
每个Java对象都可以关联一个Monitor对象,Monitor对象是由操作系统给出的,如果使用synchronized给对象上锁(重量级)之后,该对象头的Mark Word中就被设置为指向Monitor对象的指针。

image.png

  • 刚开始Monitor中Owner为null
  • 当Thread-2执行synchronized(obj)就会将Monitor的所有者Owner置为Thread-2,Monitor中只能用有一个Owner
  • 在Thread-2上锁的过程中,如果Thread-3,Thread-4,Thread-5也来执行synchronized(obj),就会进入EntryList 【BLOCLKED】
  • Thread-2执行完同步代码块的内容,然后唤醒EntryList中等待的线程来竞争锁,竞争时是非公平的
  • 图中WaitSet中的Thread-0,Thread-1是之前获得过锁,但条件不满足进入WAITING状态的线程,后面讲wait-notify时会分析

Mark Word结构为:
image.png

比如Thread-2优先执行到synchronized(obj),即使得obj去关联一个Monitor对象,obj中的Mark Word指向Monitor的地址。
当Thread-1执行到synchronized时,首先看obj是否已经关联了一个Monitor对象,发现确实是关联了,即obj已经上锁,那么该线程只能进入EntryList等待,当Thread-2线程退出synchronized后,则进入解锁状态,通过obj的Mark Word找到Monitor对象,并将Monitor对象的Owner置空,代表Thread-2释放锁。Monitor的Owner清除,并从EntryList中选择一个线程作为Owner。

image.png
这里有一个小细节:obj中Mark Word原来的hashcode信息等,是要存放在Monitor对象中的,即Monitor对象有字段可以存储未加锁状态的Mark Word信息。

注意:

  1. synchronized必须是进入同一个对象的monitor才有上述的效果<br /> synchronizedobj对象上锁,上的是**重量级锁,且只有重量级锁才会关联Monitor对象**<br /> 不加synchronized的对象不会关联监视器monitor,不遵从以上规则<br /> 执行完synchronized同步块后是要释放锁的,因为拿锁就是要去执行synchronized块才拿,所以执行完同步代码块当然要释放锁。

综上,synchronized(obj)原理是将obj关联一个monitor对象,即给obj对象上锁,注意这个描述,不是对象锁,而是给对象上锁

所以,给对象上重量级锁==synchronized(obj)==使obj对象关联一个monitor,monitor等价于锁