当不同的线程针对相同的数据却读到了不同的值时就发生了内存一致性错误。内存一致性错误的原因是非常复杂的。幸运的是我们程序员不需要详细的理解这些原因,我们需要做的事情就是使用策略来规避这些。
避免内存一致性错误的关键就是需要先理解happens-before
关系。这个关系只是简单保证了一个确定语句所写的内存对另外一个确定的语句来说是可见的。为了更好的明白这个,来看看下面这个例子。假设一个简单的int
是这样被定义和初始化:
int counter = 0;counter
能被线程A和B访问。假设线程A使变量增加:
counter++;
然后,线程B将它的值打印出来:
System.out.println(counter);
如果这两个语句在同一个线程中运行,那么可预见打印出来的值会是1,但是如果两个语句运行在不同的线程中,那么打印出来的值可能是0,因为没有办法保证线程A改变的counter
值对线程B是可见的,除非我们程序员能够确保这两个语句之间的关系是happens-before
。
有很多方法是实现happens-before
。方法之一就是使用同步。