????????在多线程并发中synchronized一直存在,很多人把它称为重量级锁,但随着JavaSE1.6对sycnhronized进行了各种优化后,有些情况就不再那么重了。
接下来详解一下JavaSE 1.6为了减少获得锁和释放锁带来的性能消耗并引入了偏向锁和轻量级锁,以及锁的存储结构和升级过程
利用synchronized实现同步的基础:Java中每一个对象都可以作为锁。
当一个线程视图访问同步代码块时,它首先必须先得到锁。退出或抛出异常时必须释放锁。
????????在JVM规范中,可以看到Synchonized在JVM的实现原理,JVM基于进入和退出Monitor对象来实现方法同步和代码块同步,但二者的实现细节不一样。
????????代码块同步是使用monitorenter和monitorexit指令实现的,而方法同步是使用另外一种方式实现,细节jvm并没有详细说明。但是方法的同步同样也可以实现者两个指令
????????jvm要保证每个monitorenter必须有对应的monitorexit与之匹配,任何对象都有一个monitor与之关联。当一个monitor被持有后,它将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor的所有权,即尝试获得对象的锁。
synchronized用的锁是存在Java对象头里的。(32位机,一字宽等于4字节)
Java对象头里的Mark Word里默认存储对象的HashCode、分代年龄和锁标记位。
32位JVM的Mark Word的默认存储结构如表2-3所示。
????????在运行期间,Mark Word里存储的数据会随着锁标志位的变化而变化。Mark Word可能变化为存储以下4种数据,如表2-4所示。
?
Java SE1.6 减少获得锁和释放锁带来的性能消耗,引入了偏向锁🔒和轻量级锁🔒。
在Java SE 1.6中,锁一共有四种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。
这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级,目的是:为了提高获得锁和释放锁的效率。
下一篇文章 =》偏向锁