Jack Shirazi在Java Performance Tuning中写道:
这意味着变量的访问和更新是自动同步的(只要它们不是长整数或双精度数)。如果一个方法只包含一个变量访问或赋值,就没有必要为了线程安全而使其同步,并且出于性能考虑不这样做的所有理由。线程安全进一步扩展到独立于任何其他变量值访问或分配给变量的任何语句集。
根据上面的描述,操作 likeflag = true
总是原子的,不需要synchronize
.
但是,这里有另一篇文章将以下情况视为数据竞争:
class DataRaceExample {
static boolean flag = false;//w0
static void raiseFlag() {
flag = true;//w1
}
public static void main(String... args) {
ForkJoinPool.commonPool().execute(DataRaceExample::raiseFlag);
while (!flag);//r_i, where i ∈ [1, k), k may be infinite
System.out.print(flag);//r
}
}
作者说:
现在,所有执行都有数据竞争,因为标志不是易失的
这两篇文章之间的冲突让我很困惑。