每一个Java对象都可以作为锁。具体表现形式有3种:
- 普通同步方法,锁就是当前实例对象。
- 静态同步方法,锁就是当前类的Class对象。
- 同步代码块,锁就是synchronized后括号里面配置的对象。
线程在进入同步块时要获取锁,退出时或者抛出异常时要释放锁。那么这个锁到底是什么呢?锁又存储在哪呢?
其实在Java中,每一个对象都关联着一个monitor,当且monitor被持有时,该对象被锁定。所以当线程进入同步块时,首先会尝试获取对象所对应的monitor的所有权,即尝试获取对象的锁。
synchronized用的锁存储在对象头中。对象头占2个字长(32bit的虚拟机中,1字长=32bit)。对象头中存储着:
- Mark Word
- Hashcode
- age
- 锁标志位
- Class Word
- 存储着指向对象类型的指针
注意,在运行过程中,Mark Word中的内容会随着锁标志位的变化而变化。