锁优化

锁优化

自旋锁与自适应自旋:

自旋:如果线程可以很快获得锁,那么可以不在OS层挂起线程,而是让线程做几个忙循环,那么就是自旋

自适应自旋:自旋的时间不再固定,而是由前一次在同一个锁上的自旋时间和锁的拥有者状态来决定

适用在:如果锁被占用时间很短,自旋成功,那么能节省线程挂起、以及切换时间,从而提升系统性能

如果锁被占用时间很长,自旋失败,会白白耗费处理器资源,降低系统性能

锁消除:

在编译代码的时候,检测到根本不存在共享数据竞争,自然也就无需同步加锁了;通过: -XX:+EliminateLocks来开启

❤同时要使用-XX:+DoEscapeAnalysis开启逃逸分析,所谓逃逸分析:(1)如果一个方法中定义的一个对象,可能被外部方法引用,称为方法逃逸

(2)如果对象可能被其他外部线程访问,称为线程逃逸,比如赋值给类变量或者可以在其他线程中访问的实例变量

锁粗化:

❤通常我们都要求同步块要小,但一系列连续的操作会导致对一个对象反复的加锁和解锁,这会导致不必要的性能损耗。这种情况建议把锁同步的范围加大到整个操作序列。

轻量级锁:

轻量级相对于传统锁机制而言,本意是没有多线程竞争的情况下,减少传统锁机制使用OS实现互斥所产生的性能损耗。

其实现原理很简单,就是类似乐观锁的方式

如果轻量级锁失败,表示存在竞争,升级为重量级锁,导致性能下降

偏向锁:

偏向锁是在无竞争情况下,直接把整个同步消除了,连乐观锁都不用,从而提高性能,所谓的偏向,就是偏心,即锁会偏向于当前已经占有锁的线程

只要没有竞争,获得偏向锁的线程,在将来进入同步块,也不需要做同步

当有其他线程请求相同的锁时,偏向模式结束

如果程序中大多数锁总是被多个线程访问的时候,也就是竞争比较激烈,偏向锁反而会降低性能

使用-XX:-UseBiasedLocking来禁用偏向锁,默认开启

JVM中获取锁的步骤:

会先尝试偏向锁;然后尝试轻量级锁

再然后尝试自旋锁

最后尝试普通锁,使用OS互斥量在操作系统层挂起

同步代码的基本规则:

尽量减少锁持有的时间

尽量减小锁的粒度(锁里面包含的功能不要太多,要精简)

---- The end of this article ----