【Java并发编程】内存一致性错误
2017-07-25 22:44
531 查看
内存一致性错误说的是:不同线程看到的内存中的同一份数据却有不同的“视图”。这个时候我们们说发生了内存一致性错误。内存一致性错误是我们应该避免的。
而避免内存一致性错误的关键在于理解“happens-before”关系。这个关系保证了向内存中写入的一条语句可以被其他语句“看到”。我们来看下面的例子:
初始化变量counter,该变量在线程A和线程B中间共享
线程A先执行
接着线程B执行
这个输出结果是多少呢,可能是1,可能是0。但是具体是哪一个是不能确定的。如果该过程不是在两个线程中执行,而是在同一个线程中执行,那么我们可以断定结果一定是1。但是由于是在两个线程中共享counter变量,当A对counter进行了自增后,没有什么可以保证线程B可以看见线程A对counter的改动。除非我们将两条语句建立了上述所说的那种“happens-before”的关系。
有许多方法保证这种关系,其中一个方法就是采取“同步”的方法。
当我们通过Thread.start方式启动一个线程。任何和该语句有“happens-before”的关系的。都与该线程中任何的语句有“happens-before”的关系。该处设计的目的是为了让创建该线程的语句可以被这个新线程看到。
Thread.join的线程可以看见宿主线程执行过的变量
而避免内存一致性错误的关键在于理解“happens-before”关系。这个关系保证了向内存中写入的一条语句可以被其他语句“看到”。我们来看下面的例子:
初始化变量counter,该变量在线程A和线程B中间共享
int counter = 0;
线程A先执行
counter++;
接着线程B执行
System.out.println(counter);
这个输出结果是多少呢,可能是1,可能是0。但是具体是哪一个是不能确定的。如果该过程不是在两个线程中执行,而是在同一个线程中执行,那么我们可以断定结果一定是1。但是由于是在两个线程中共享counter变量,当A对counter进行了自增后,没有什么可以保证线程B可以看见线程A对counter的改动。除非我们将两条语句建立了上述所说的那种“happens-before”的关系。
有许多方法保证这种关系,其中一个方法就是采取“同步”的方法。
当我们通过Thread.start方式启动一个线程。任何和该语句有“happens-before”的关系的。都与该线程中任何的语句有“happens-before”的关系。该处设计的目的是为了让创建该线程的语句可以被这个新线程看到。
Thread.join的线程可以看见宿主线程执行过的变量
相关文章推荐
- 【Java并发编程】之十七:深入Java内存模型—内存操作规则总结 (r)
- 【Java并发编程】之十五:并发编程中实现内存可见的两种方法比较:加锁和volatile变量
- 【Java并发编程】之十七:深入Java内存模型—内存操作规则总结
- 【Java并发编程】:深入Java内存模型—内存操作规则总结
- 【Java并发编程】之十五:并发编程中实现内存可见的两种方法比较:加锁和volatile变量
- 【Java并发编程】6、volatile关键字解析&内存模型&并发编程中三概念
- 并发编程之 Java 内存模型 + volatile 关键字 + Happen-Before 规则
- 【Java并发编程】之十七:深入Java内存模型—内存操作规则总结
- 【Java并发编程】:深入Java内存模型—内存操作规则总结
- Java 并发编程__内存模型、线程同步机制
- 【Java并发编程】:图文讲述同步的另一个重要功能:内存可见性
- 字节码防止内存错误及提高代码质量-Java基础-Java-编程开发
- 【Java并发编程】之十四:图文讲述同步的另一个重要功能:内存可见性
- 并发编程笔记(三):Java 内存模型(二)
- 【翻译八】java-内存一致性错误
- 【Java并发编程】之十七:深入Java内存模型—内存操作规则总结
- 【Java并发编程】之十四:图文讲述同步的另一个重要功能:内存可见性
- Java 高并发第二阶段实战---高并发设计模式,内存模型,CPU一致性协议,volatile关键字剖析
- 【Java并发编程】之十五:并发编程中实现内存可见的两种方法比较:加锁和volatile变量
- 【Java并发编程】之十四:图文讲述同步的另一个重要功能:内存可见性