①. Synchronized的性能变化
①. java5以前,只有Synchronized,这个是操作系统级别的重量级操作,重量级锁,假如锁的竞争比较激烈的话,性能下降
②. 在Java早期版本中,synchronized属于重量级锁,效率低下,因为监视器锁(monitor)是依赖于底层的操作系统的Mutex Lock来实现的,挂起线程和恢复线程都需要转入内核态去完成,阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态切换需要耗费处理器时间,如果同步代码块中内容过于简单,这种切换的时间可能比用户代码执行的时间还长”,时间成本相对较高,这也是为什么早期的synchronized效率低的原因
Java 6之后,为了减少获得锁和释放锁所带来的性能消耗,引入了轻量级锁和偏向锁
③. 为什么每一个对象都可以成为一个锁?
Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中 ,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁。
Monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的转换,成本非常高
④. Mutex Lock
Monitor是在jvm底层实现的,底层代码是c++。本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的转换,状态转换需要耗费很多的处理器时间成本非常高。所以synchronized是Java语言中的一个重量级操作。
⑤. Java 6之后,为了减少获得锁和释放锁所带来的性能消耗,引入了轻量级锁和偏向锁,需要有个逐步升级的过程,别一开始就捅到重量级锁
⑥. synchronized锁:由对象头中的Mark Word根据锁标志位的不同而被复用及锁升级策略
②. 无锁
- ①. 代码展示
public class MyObject{ public static void main(String[] args){ Object o = new Object(); System.out.println("10进制hash码:"+o.hashCode()); System.out.println("16进制hash码:"+Integer.toHexString(o.hashCode())); System.out.println("2进制hash码:"+Integer.toBinaryString(o.hashCode())); System.out.println( ClassLayout.parseInstance(o).toPrintable()); } }
<!-- JAVA object layout 官网:http://openjdk.java.net/projects/code-tools/jol/ 定位:分析对象在JVM的大小和分布 --> <dependency> <groupId>org.openjdk.jol</groupId> <artifactId>jol-core</artifactId> <version>0.9</version> </dependency>
②. 程序不会有锁的竞争