【发布时间】:2012-03-10 22:17:25
【问题描述】:
正如标题所示,我正在寻找一种比较和交换的实现,但具有大于比较:
if(newValue > oldValue) {
oldValue = newValue;
}
其中oldValue 是某个全局共享状态,newValue 是每个线程私有的,无需这样做:
synchronized(locker) {
if(newValue > oldValue) {
oldValue = newValue;
}
}
因为我想要一个非阻塞的解决方案。通过研究其他非阻塞操作的源代码,我想出了这个(假设值是整数):
AtomicInteger oldValue; // shared global variable
...
public boolean GreaterThanCAS(int newValue) {
while(true) {
int local = oldValue;
if(local == oldValue) {
if(newValue > local) {
if(oldValue.compareAndSet(local, newValue) {
return true; // swap successful
} // else keep looping
} else {
return false; // swap failed
}
} // else keep looping
}
}
当// else keep looping发生时,意味着另一个线程同时更改了oldValue,所以我需要循环再试一次。
这个实现是否正确(线程安全)?
【问题讨论】:
-
这只是检查分配
local变量和检查它们是否相同之间是否发生线程切换。在您的 if 语句之后可能会发生线程切换。所以不,这不是线程安全的,但没有阻塞我不确定你是否会找到解决方案。 -
@Shaded:如果
oldValue不等于local,oldValue.compareAndSwap(local, newValue)调用也会返回 false,因此它也会在此处检查。 -
您不需要先进行相等比较。只要“if(newValue>local) oldValue.CAS(local, newValue) else repeat”就足够了
-
putIfGreater或者更好的方法名称。 -
(而
oldValue是一个非常奇怪的名字。希望它不是真正的全球性。)
标签: java multithreading synchronization nonblocking