gpt4 book ai didi

java - compare-and-swap和blocking算法的性能比较

转载 作者:行者123 更新时间:2023-11-29 05:10:46 25 4
gpt4 key购买 nike

我有一个 ConcurrentLinkedQueue 用作底层数据结构。在每次 put 调用中,我都会向列表中添加一个唯一的增量值。我有此方法的同步版本和比较和交换版本。当我只有很少的线程(例如 5 个)并且总共执行 1000 万次输入时,我发现同步版本的效果要好得多。当我有很多线程(例如 2000)并且总共执行相同数量的 puts 时,我发现 CAS 工作得更好。为什么 CAS 与线程较少的阻塞算法相比表现不佳?

// AtomicReference<Foo> latestValue that is initialized
public void put(Double value) {
Foo currentValue;
while (true) {
currentValue = latestValue.get();
Foo newValue = new Foo(value);
if (latestValue.compareAndSet(currentValue, newValue)) {
historyList.add(newValue);
return;
}
}
}

统计

NON-BLOCKING
Threads 2000
Puts per thread 10000
Put time average 208493309

BLOCKING
Threads 2000
Puts per thread 10000
Put time average 2370823534


NON-BLOCKING
Threads 2
Puts per thread 10000000
Put time average 13117487385

BLOCKING
Threads 2
Puts per thread 10000000
Put time average 4201127857

最佳答案

TL;DR 因为在无竞争的情况下,JVM 将优化synchronized 并将其替换为 CAS 锁。

在您的 CAS 案例中,您有开销:即使您的 CAS 会失败,您仍在尝试进行一些计算。当然,与真正的互斥量获取相比,这没什么,当您使用 synchronized 时通常会发生这种情况。

但是 JVM 并不愚蠢,当它看到您当前获取的锁不满足时,它只是用 CAS 锁替换真正的互斥锁(甚至在偏向锁定的情况下用简单的存储)。因此,对于 synchronized 情况下的两个线程,您仅测量一个 CAS,但在您自己的 CAS 实现的情况下,您还测量分配 Foo 实例、compareAndSet 和 get() 的时间。

对于 2000 个线程,JVM 不执行 CAS 优化,因此您的实现优于预期的互斥量获取。

关于java - compare-and-swap和blocking算法的性能比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28631565/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com