在JDK1.5之后,JVM开发团队对Synchronized关键进行了优化,并且实现了各种锁优化技术,并且各种测试表明Synchronized并不比ReentrantLock慢,下面就一起看看Synchronized的锁升级以及有哪些锁优化吧~
自旋锁和自适应自旋锁
自旋锁
-
什么是自旋锁
是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
自旋锁的默认自选次数是10次,可以通过JVM参数
-XX:PreBlockSpin
进行修改 -
为什么需要自旋锁
Java的线程是映射到操作系统的原生内核线程之上的(线程是通过操作系统的内核线程实现的,并且创建出来的线程通过操作系统内核进行调度),如果要阻塞或唤醒一条线程,则需要操作系统来完成,而应用程序运行在用户空间,线程需要在内核空间中进行调度,不可避免的需要在内核态和用户态之间进行转换,这种转换需要耗费很多处理器的时间,所以重量级锁的操作是非常耗时也是因为线程的阻塞和唤醒。
自旋锁的缺点:
自选次数无法确定,如果自选可以获取到锁,那么自选就是有价值的,但是如果一直自选都无法获取到锁,那么就会一直在浪费CPU资源。所以JVM中自选的默认次数是十次,如果超过自选次数没有获取到锁,就会将线程阻塞。使用JVM参数**-XX:PreBlockSpin**修改自选次数
自适应自旋锁
-
什么是自适应自旋锁
自适应自旋锁就是为了解决自旋锁的缺点,防止过多自旋获取自选可以获取到锁,但是自旋的次数到了的问题。自适应自旋即自旋的次数和时间不是固定的了,而是通过前一次的经验来判断,如果前一次在同一锁上通过自选获取到了锁,那么会认为这次也可以获取到锁,则自选的次数和时间就会更多一些,如果自旋的过程中很少获取到锁,那么可以减少自旋或直接不自旋,将线程阻塞,因为自旋也是浪费CPU资源。
通过自适应自旋,程序执行的时间越长,那么JVM对锁的信息情况就会越来越准确,自适应自旋的价值就越大。
锁消除
-
什么是锁消除
锁消除是指在JVM在JIT即时编译时优化代码的一种方式(想了解JIT即时编译的小伙伴看这篇文章哦运行期编译优化),主要是将不需要同步的代码从同步代码块中移除,提升执行效率。
-
锁消除原理
锁消除可以实现的原理是基于JIT编译的优化方式之一—逃逸分析,当代码没有发生逃逸,会将该变量分配在栈上,那么该对象没有逃逸到线程之外,则该对象就是线程私有的,不会出现多线程的数据一致性和安全性问