Java虚拟机的锁优化策略

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/J080624/article/details/82463399

【1】自旋锁

① 背景

互斥同步对性能最大的影响的阻塞,挂起和恢复线程都需要转入内核态中完成。并且通常情况下,共享数据的锁定状态只持续很短的一段时间,为了这很短的一段时间进行上下文切换并不值得。

② 原理

当一条线程需要请求一把已经被占用的锁时,并不会进入阻塞状态,而是继续持有CPU执行权等待一段时间,该过程称为“自旋”。

③ 优点

由于自旋等待锁的过程,线程并不会引起上下文切换,因此比较高效。

④ 缺点

自旋等待过程线程一直占用CPU执行权但不处理任何任务,因此若该过程过长,那就会造成CPU资源的浪费。

⑤ 自适应自旋

自适应自旋可以根据以往自旋等待时间的经验,计算出一个较为合理的本次自旋等待时间。


【2】锁清除

编译器会清除一些使用了同步,但同步块中没有涉及共享数据的锁,从而减少多余的同步。


【3】锁粗化

若有一系列的操作,反复地对同一把锁进行上锁和解锁操作,编译器会扩大这部分代码的同步块的边界,从而只使用一次上锁和解锁操作。


【4】轻量级锁

① 本质

使用CAS取代互斥同步。

CAS是什么?互斥同步又是什么?
.
所谓互斥,就是不同线程通过竞争进入临界区(共享的数据和硬件资源),为了防止访问冲突,在有限的时间内只允许其中之一独占性的使用共享资源。如不允许同时写。
.
同步关系则是多个线程彼此合作,通过一定的逻辑关系来共同完成一个任务。一般来说,同步关系中往往包含互斥,同时对临界区的资源会按照某种逻辑顺序进行访问。如先生产后使用。
.
与锁相比,使用比较交换(CAS)会使程序看起来更加复杂一些,但由于其非阻塞性,它对死锁免疫。更重要的是,使用无锁的方式完全没有锁竞争带来的系统开销,也没有线程频繁调度带来的开销,因此,它是比基于锁的优势的方式拥有更优越的性能。
.
CAS算法的过程是这样:它包含三个参数CAS(V,E,N)。V表示要更新的值,E表示预期值,N表示新值。仅当V等于E时,才会将V的值设为N,如果V值和E值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后,CAS返回当前V的真实值。CAS操作一个变量时,只有一个会胜出,并更新成功,其余均会失败。失败的线程不会被挂起,仅是被告知失败 ,并且允许再次尝试,当然也允许失败的线程放弃操作。
.
基于这样的原理,CAS操作即使没有锁,也可以发现其他线程对当前线程的干扰,并进行恰恰当的处理。

② 背景

轻量级锁是相对于重量级锁而言的,而重量级锁就是传统的锁。


③ 轻量级锁与重量级锁的比较

重量级锁是一种悲观锁,它认为总是有多条线程要竞争锁,所以它每次处理共享数据时,不管当前系统中是否真的有线程在竞争锁,它都会使用互斥同步来保证线程的安全。

而轻量级锁是一种乐观锁,它认为锁存在竞争的概率比较小,所以它不使用互斥同步,而是使用CAS操作来获得锁。这样能减少互斥同步所使用的互斥量带来的性能开销。


④ 实现原理

对象头称为Mark Word,虚拟机为了节约对象的存储空间,对象处于不同的状态下,Mark Word中存储的信息也有所不同。

Mark Word中有个标志位用来表示当前对象所处的状态。

当线程请求锁时,若该锁对象的Mark Word中标志位为01(未锁定状态),则在该线程的栈帧中创建一块名为“锁记录”的空间,然后将锁对象的Mark Word拷贝至该空间。最后通过CAS操作将锁对象的Mark Word指向该锁记录。

若CAS操作成功,则轻量级锁的上锁过程成功。

若CAS操作失败,再判断当前线程是否已经持有了该轻量级锁。若已经持有,则直接进入同步块;若尚未持有,则表示该锁已经被其他线程占用,此时轻量级锁就要膨胀成重量级锁。


⑤ 前提

轻量级锁比重量级锁性能更高的前提是,在轻量级锁被占用的整个同步周期内,不存在其他线程的竞争。若在该过程中一旦有其他线程竞争,那么就会膨胀成重量级锁,从而除了使用互斥量外,还额外发生了CAS操作,因此更慢!


【5】偏向锁

① 作用

偏向锁是为了消除无竞争情况下的同步原语,进一步提升程序性能。

② 与轻量级锁的区别

轻量级锁是在无竞争的情况下使用CAS操作来代替互斥量的使用,从而实现同步;而偏向锁是在无竞争的情况下完全取消同步。

③ 与轻量级锁的相同点

它们都是乐观锁,都认为同步期间不会有其他线程竞争锁。

④ 原理

当线程请求到锁对象后,将锁对象的状态标志位改为01,即偏向模式。然后使用CAS操作将线程的ID记录在锁对象的Mark Word中。以后该线程可以直接进入同步块,连CAS操作都不需要。但是一旦有第二条线程需要竞争锁,那么偏向模式立即结束,进入轻量级锁的状态。

⑤ 优点

偏向锁可以提高有同步但没有竞争的程序性能。但是如果锁对象时常被多条线程竞争,那偏向锁就是多余的。

偏向锁可以通过虚拟机的参数来控制它是否开启。·

猜你喜欢

转载自blog.csdn.net/J080624/article/details/82463399