【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
高效并发是从JDK1.5到1.6的重要改进,HotSpot虚拟机开发团队在这个版本花费大量精力去实现各种锁优化技术,例如:适应性自旋,锁消除,锁出花,轻量锁,偏向锁等。
自旋锁与自适应自旋
为了处理互斥同步引来的性能下降,如果物理机有一个以上的处理器(现在基本都是多个处理器了),能让两个或者两个以上的线程同时并行执行,我们就可以让后面请求锁的那个线程“稍等一下”,但是不放弃处理器执行时间,看看持有锁的线程是否很快就会释放锁。,为了让线程等待,值需要让线程执行一个忙循环(自旋),这就是所谓的自旋锁。
自旋等待本顺虽然避免了线程切换的开销,但是它要占用处理器的时间,因此,如果锁被占用的时间很短,自旋效果就非常好,反之只会白白消耗cpu资源,因此,自旋等待时间必须有一定的限度,如果超过了限定的次数仍然没有成功获得锁,就当使用传统的方法去挂起线程。自旋默认的次数是10次。
JDK1.6引入了自适应自旋锁,自适应意味着等待时间不再固定,而是由上一次再同一个锁上的自旋时间以及锁的拥有者的状态来决定。
如果再同一个对对象上,自旋刚刚成功获得过锁,并且持有锁的线程正在运行中,那么虚拟机就认为这次自旋也很有可能再次成功,进而它讲允许自旋等待相对更长的时间。反之自旋很少成功获得过锁,那以后或者锁时可能省略掉自旋过程。
锁消除
锁消除是指再虚拟机即时编译器再运行时,如果检测到有代码不可能存在共享数据竞争时,却还加了锁,就会主动删除掉锁。这项技术来源于逃逸分析的数据支持。
粗化锁
我们编写代码的时候,都本能的将synchornized的范围定义的尽量小,这样可以提高获取锁的可能性。但是如果一些列连续操作都对同一个对象返回加锁和解锁,甚至加锁操作是出现在循环中,那即使没有线程竞争,频繁的进行阻塞同步操作也会导致不必要的性能损耗。
例如String 在拼接字符串的时候如果连续的append()操作都要加锁,还不如把加锁范围扩展到第一个append()到最后一个append(),只加一次锁。
轻量级锁
CAS就属于这一类。
偏向锁
偏向锁的“偏”是偏心的意思。它的意思是这个锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将永远不需要再进行同步。
来源:oschina
链接:https://my.oschina.net/passenger85/blog/3153148