synchronized实现同步的基础:Java中的每一个对象都可以作为锁。
3种表现形式:
- 对于普通的同步方法,锁的是当前实例对象。
- 对于静态同步方法,锁的是当前类的Class对象。
- 对于同步方法块,锁的是synchronized括号里配置的对象。
实现原理
从JVM规范中看出synchronized在JVM中里的实现原理。JVM基于进入和退出Monitor对象来实现方法同步和代码块同步。代码块同步使用的是monitorenter和monitorexit指令来实现,方法同步则是通过另一种方式实现,细节在JVM中没有说明,但是方法同步同样可以使用这个两个指令来实现。
monitorenter指令是在编译后插入到同步代码块的开始位置,monitorexit插入到方法结束处和异常处,JVM要保证每个monitorenter都有一个monitorexit与之配对。
任何对象都有一个monoitor与之关联,当monitor被持有后,对象处于锁定状态。当线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即获取对象的锁。
Java对象头
synchronized用的锁是存在Java对象头里的。
Java对象头里的Mark Word里默认存着对象的HashCode、分代年龄和锁标记位。
在运行期间,Mark Word里存储的数据会随着锁标志位的变化而变化。
锁的升级与对比
在JavaSE 1.6中,锁有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这个几种状态会随着竞争情况逐渐升级。锁可以升级但不能降级,目的是为了提高获得锁和释放锁的效率。