首页 > 解决方案 > 变量的不同步读/写可能导致数据竞争?

问题描述

Jack ShiraziJava 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
  }
}

作者说:

现在,所有执行都有数据竞争,因为标志不是易失的

这两篇文章之间的冲突让我很困惑。

标签: javaconcurrencythread-safetydata-racenon-thread-safe

解决方案


杰克·希拉兹错了。

原始变量的访问和更新,例如int原子的,但不是同步的。

因为它是原子的,所以可以通过使其成为完全线程安全的volatile。否则,在不同内核上运行的其他线程可能会看到陈旧的值,因为CPU 缓存尚未刷新。


推荐阅读