赣州新闻网

首页 / 科技

使用乐观锁优化并发性能

2020-04-01 · 赣州新闻网 · 科技

什么是乐观锁?

乐观锁,顾名思义,就是说在操作共享资源时,它总是抱着乐观的态度进行,它认为自己可以成功地完成操作。但实际上,当多个线程同时操作一个共享资源时,只有一个线程会成功,那么失败的线程呢?乐观锁不会像悲观锁一样在操^ J w F E s w & w作系统中挂起,而仅仅是返回,并且系统允许失败的线程重试,也允许自动放弃退出操作。

所以,乐观锁相. I *比悲c S 1 O d %观锁来说,不会带来死锁、饥饿等活性故障问题,线程间的相互影响也远远比悲观锁要小。更为重要的是,乐观锁没有_ } e 9因竞争造成的! 2 !系统开销,所以在性能上也是更胜一筹。

乐观锁的实现原理

​CAS 是实现乐观锁的核心算法,它包含了e X w - 0Set 方法中使用了 for 循环不断重试 CAS 操作,如果长时间不成功,就会给 CPU 带来非常大~ & h u U e - : y的执行开销。到了 Java8,for* @ T 9 @ 0 3 S J 循环虽然被去掉了,但我们反编译 U- 0 Wnsafe 类时就可以发现该循环其实是被封装在了 Unsafe 类中,CPU 的执行开销依然存在。

   public final int getAndSet(int newVr 6 9 d g ; H o ?alue) {
while (true) {
int current = get();
if (compareAndSet(current, newValue))
return current;
}
}

​在 JDK1.8 中,Java 提供了一个新的原子类 LongAdder。LongAdder 在高并发场景下会比 AtomicInteger 和 AtomicLong 的性能更好,代价就是+ y P * : !会消耗更多的内存空间。

测试对比

​我们分别在“读多写少”、“读少写多”、“读写差不多”这三种场景下` m q B #进行测试。

​对三种模式下的五个锁 Synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLoc l e -k 以及乐观锁 LongAdder 进行压测。压测结果如下图:

使用乐观锁优化并发性能

​通过以上结果A } o F 2 H R,我们可以发现:

在写大于w v P读的场景下,乐观锁的性能是最好的,其它x + X 4 种锁的性能则相差不多;

在读和Y W L O写差不多的场景下,两种读写锁A G t = z r T 0以及乐观锁的性能要优于 Synchronized 和 ReentrantLock。在读大于写的场Y y a *景下,读写锁t L e e G ( % 6 ReentrantRe8 X 7 ? x iadWriteLock、StampedLock 以及乐观锁的读写性能是最好的。

测试被封设置于都到了影响性能乐观锁优化