# 内存一致性错误

当不同的线程对于相同数据不一致时,会发生 内存一致性错误。内存一致性错误的原因很复杂, 超出了本教程的范围。幸运的是,程序员不需要详细了解这些原因。所有需要的是避免这种情况的策略。

避免内存一致性错误的关键在于理解之前的关系。这种关系只是保证一个特定语句的内存写入对另一个特定语句是可见的。 要看到这一点,请考虑以下示例。假设一个简单的 int 字段被定义和初始化:

int counter = 0;
1

counter字段在两个线程 A 和 B 之间共享。假设线程 A 递增 counter

counter++
1

然后不久之后,线程 B 打印出来 counter

System.out.println(counter);
1

如果两个语句在同一个线程中被执行,那么假定打印出来的值将为“1”是安全的。但是如果两个语句在单独的线程中执行, 则打印输出的值可能为“0”,因为不能保证线程 A 的更改 counter 对于线程 B 是可见的,除非程序员已经建立了这些两个声明

有几个操作创建发生之前(happens-before)的关系。其中一个是同步,我们将在以下部分中看到。

我们已经看到了两个创建发生关系的动作:

  1. 当一个语句被调用 Thread.start 时,每个与该语句发生关系的语句也与新线程执行的每个语句都有一个发生关系。导致新线程创建的代码的效果对于新线程是可见的。

  2. 当线程终止并导致 Thread.join 另一个线程返回时,由终止的线程执行的所有语句与成功连接之后的所有语句都有一个发生关系。线程中的代码的效果现在对执行连接的线程是可见的。

对于这一系列的动作建立 happens-before 关系,指的汇总页 java.util.concurrent包

这里的两个操作描述我第一个没有看懂。翻译太蛋疼了。 第二个的 Thread.join,也是相当于让线程顺序执行了。