关于内存可见性的小问题。
代码示例 1:
class CustomLock {
private boolean locked = false;
public boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
此代码在多线程环境中容易出现错误,首先是因为“if-then-act”不是原子的,其次是因为潜在的内存可见性问题,例如 threadA 将字段设置为 true,但 threadB后来希望读取该字段的值可能看不到,但仍然看到该值是假的。
最简单的解决方案是使用 synchronized 关键字,如 CodeSample2。
代码示例2:
class CustomLock {
private boolean locked = false;
public synchronized boolean lock() {
if(!locked) {
locked = true;
return true;
}
return false;
}
}
现在,如果我希望使用原子变量,例如 AtomicBoolean(问题适用于所有原子变量),该怎么办?
代码示例 3:
public static class CustomLock {
private AtomicBoolean locked = new AtomicBoolean(false);
public boolean lock() {
return locked.compareAndSet(false, true);
}
}
除了更好的性能考虑之外,我们可以看到现在我们已经使用 AtomicBoolean 实现了与CodeSample1中的“if-then-act”类似的逻辑。代码在逻辑上做什么并不重要,我的问题是,如果 2 个线程几乎同时调用CodeSample3中的 lock() 方法会怎样,而很明显,现在对该字段的任何写入操作都将以原子方式完成,使用 AtomicBoolean 是否也保证了内存可见性?
对不起,长篇大论,只是想确保我尽可能清楚地表达出来,谢谢大家...