返回

Java并发编程中自旋锁会浪费 CPU 资源并导致错误

发布时间:2023-11-01 06:04:31 216

在并发编程中,自旋锁(spin locks )想必大家都不陌生。

自旋锁一个非常经典的使用场景是CAS(即比较和交换),是一种无锁的思想(说白了就是使用了无限循环),用来解决更新数据的问题高并发场景。

atomic包下的很多类,如AtomicInteger、AtomicLong、AtomicBoolean等,都是用CAS实现的。

我们以AtomicInteger类为例,它incrementAndGet不会每次都给变量加 1。

public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

它的底层是用自旋锁实现的:

public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

return var5;
}

在do…while无限循环中,不断地进行数据的比较和交换。如果一直失败,就会一直重试。

在高并发的情况下,compareAndSwapInt大概率会失败,从而导致CPU不断自旋,严重浪费CPU资源。

那么,如果这个问题解决了呢?

解决方案是使用LockSupport类的方法parkNanos。

private boolean compareAndSwapInt2(Object var1, long var2, int var4, int var5) {
if(this.compareAndSwapInt(var1,var2,var4, var5)) {
return true;
} else {
LockSupport.parkNanos(10);
return false;
}
}

当CAS失败时,调用LockSupport类的parkNanos方法进行睡眠,这相当于调用Thread.Sleep方法。

这样可以有效减少因频繁旋转而造成的CPU资源过度浪费的问题。

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线