考虑以下 Java 程序:
static volatile int shared;
public static void main(final String[] args) {
final Runnable r = () -> {
shared = 1;
};
new Thread(r).start();
new Thread(r).start();
}
因为shared
被标记volatile
,我想说这个程序没有数据竞争。但是,如何基于 JLS(例如,版本 11)来激发这一点?
第 17 章告诉我们:
当一个程序包含两个冲突的访问(第 17.4.1 节)时,这些访问没有按发生前的关系排序,则称为包含数据竞争。
我认为这是 JLS 提供的数据竞争的定义。然后我们有第 17.4.1 节告诉我们:
如果至少有一次访问是写入,则对同一变量的两次访问(读取或写入)称为冲突。
好的,所以我们在这里有冲突的访问,因为我们有两次写入shared
. 现在我们必须在两个写入之间建立起之前发生的关系,否则我们就会有比赛。然而,我没有设法找到为什么我们在这里有这种关系。第 17 章告诉我:
如果动作 x 与后续动作 y 同步,那么我们也有 hb(x, y)。
同一章告诉我:
对 volatile 变量 v(第 8.3.1.4 节)的写入与任何线程对 v 的所有后续读取同步(其中“后续”根据同步顺序定义)。
但是在将写入关联到 volatile 变量之前,我还没有发现任何事情发生。这是为什么?