Memory Consistency Errors

  Memory consistency errors occur when different threads have inconsistent views of what should be the same data. The causes of memory consistency errors are complex and beyond the scope of this tutorial. Fortunately, the programmer does not need a detailed understanding of these causes. All that is needed is a strategy for avoiding them.

  The key to avoiding memory consistency errors is understanding the happens-before relationship. This relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement. To see this, consider the following example. Suppose a simple int field is defined and initialized:

int counter = 0;
The counter field is shared between two threads, A and B. Suppose thread A increments counter:

counter++;
Then, shortly afterwards, thread B prints out counter:

System.out.println(counter);
  If the two statements had been executed in the same thread, it would be safe to assume that the value printed out would be "1". But if the two statements are executed in separate threads, the value printed out might well be "0", because there's no guarantee that thread A's change to counter will be visible to thread B — unless the programmer has established a happens-before relationship between these two statements.

  There are several actions that create happens-before relationships. One of them is synchronization, as we will see in the following sections.

We've already seen two actions that create happens-before relationships.

  When a statement invokes Thread.start, every statement that has a happens-before relationship with that statement also has a happens-before relationship with every statement executed by the new thread. The effects of the code that led up to the creation of the new thread are visible to the new thread.
  When a thread terminates and causes a Thread.join in another thread to return, then all the statements executed by the terminated thread have a happens-before relationship with all the statements following the successful join. The effects of the code in the thread are now visible to the thread that performed the join.
  For a list of actions that create happens-before relationships, refer to the Summary page of the java.util.concurrent package..

译文:
内存一致性错误
  当不同的线程有不一致的访问相同的数据的时候可能会发生内存一致性错误。内存一致性错误的原因是复杂的并且超过了本课程。幸运的是,程序员并不需要知道这个原因的细节。所有需要做的是避免这种问题发生。
  避免内存一致性问题发生的关键是找到在它发生之前的关系。这种关系是内存通过指定的语句写入特定的语句的一种根本的保证。为了明白这件事情,考虑一个实例。假如一个简单int域被定义和初始化成如下:
int counter = 0;
conter域被两个线程所共享,A和B.假如A线程增加counter.
counter++;
那么,不久以后,线程B打印出counter.
System.out.println(counter);
  如果这两个语句已经在相同的线程执行,那么假设它的执行结果为输出“1”是安全的。但是,如果两个语句被分开了执行。这个执行的值可能为“0”,因为不保证线程A对counter的改变对线程B是可见的,除非程序员已经在这两个语句发生之前就确定了它们之间的关系。
  这有很多种方法创建事先的关系。其中一种就是同步方法(synchronization),我们在接下来的章节中会看到。
我们已经看到了两个创建事先的关系的方法。
  当一个语句执行thread.start方法的时候。每一个在这个语句发生之前的关系也对应的有一个语句在执行新的线程的时候有这种事先的关系。这种代码的影响导致一个新线程对另外一个新线程是可见的。
  当一个线程终止或者引起另外一个线程。连接另外一个线程返回,那么所有的终止执行语句会有一个事先的关系在所有语句在join执行成功之后。现在这种代码的影响导致一个新线程对另外允许连接这个新线程是可见的。
  看创建事先的关系的方法,可以参考java.util.concurrent包的总结。

养眼是必须滴^^

【翻译八】java-内存一致性错误的更多相关文章

  1. Java 多线程之内存一致性错误

    当不同的线程针对相同的数据却读到了不同的值时就发生了内存一致性错误.内存一致性错误的原因是非常复杂的.幸运的是我们程序员不需要详细的理解这些原因,我们需要做的事情就是使用策略来规避这些. 避免内存一致 ...

  2. Java内存一致性

    问题 前段时间在做服务注册发现的时候,有一处这样的逻辑,先发现下游服务,然后再是服务启动,服务启动完毕才能注册服务,因为注册一个在启动过程中的服务显然是不正确的设计. 然而很不巧,我们目前使用的TTh ...

  3. Java内存模型(三)原子性、内存可见性、重排序、顺序一致性、volatile、锁、final

          一.原子性 原子性操作指相应的操作是单一不可分割的操作.例如,对int变量count执行count++d操作就不是原子性操作.因为count++实际上可以分解为3个操作:(1)读取变量co ...

  4. Java内存模型深度解析:顺序一致性--转

    原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...

  5. java内存模型-顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java 内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代 ...

  6. 深入理解Java内存模型(三)——顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...

  7. 【转】深入理解Java内存模型(三)——顺序一致性

    数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞争的定义如下: 在一个线程中写一个变量, 在另一个线程读同一个变量, 而且写和读没有通过同步来排序. 当代码 ...

  8. java中三种常见内存溢出错误的处理方法

    更多 10   相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的 ...

  9. java中三种常见内存溢出错误的处理方法(good)

    相信有一定java开发经验的人或多或少都会遇到OutOfMemoryError的问题,这个问题曾困扰了我很长时间,随着解决各类问题经验的积累以及对问题根源的探索,终于有了一个比较深入的认识. 在解决j ...

随机推荐

  1. u-boot 2011.09 开启debug 调试

    以前做过,现在刚才又想不起来了,这个错误非常的严重. 在这里记一下. debug 调试信息的开启在 include/common.h 有如下宏定义: #ifdef DEBUG #define debu ...

  2. 2.6---找有环链表的开头结点(CC150)

    public ListNode detectCycle(ListNode head) { ListNode fast = head; ListNode slow = head; int flag = ...

  3. 微信app支付,服务端对接

    首先,文档不给力,不吐槽了. 遇到的坑如下: 1. mch_id和appid没有关联关 系 这个没有花太久,参考了csdn某君的建议,直接邮件给相关技术团队(wepayTS@tencent.com). ...

  4. VC中基于 Windows 的精确定时[转]

    在工业生产控制系统中,有许多需要定时完成的操作,如定时显示当前时间,定时刷新屏幕上的进度条,上位 机定时向下位机发送命令和传送数据等.特别是在对控制性能要求较高的实时控制系统和数据采集系统中,就更需要 ...

  5. 怎么安装MYSQL5.0的JDBC驱动

    1.下载mysql for jdbc driver.   http://dev.mysql.com/downloads/connector/j/3.1.htmlMySQL Connector/J is ...

  6. Java Dao设计模式

    一.信息系统的开发架构   客户层-------显示层-------业务层---------数据层---------数据库 1.客户层:客户层就是客户端,简单的来说就是浏览器. 2.显示层:JSP/S ...

  7. js中val()和value的区别

    val()是在有jQuery插件的时候才能用,value是在没有jQuery插件的情况下也能用.val()是jQuery根据原生JS里面的value写出来的函数 $(this).val(); 有四个重 ...

  8. 【leetcode】Unique Paths II

    Unique Paths II Total Accepted: 22828 Total Submissions: 81414My Submissions Follow up for "Uni ...

  9. pip 安装命令

    pip官网文档 https://pip.pypa.io/en/latest/reference/pip.html 若没有将c:\Python27\Scripts加入到path环境变量,可以在c:\Py ...

  10. ios 利用size classes 使 iPad  水平和垂直方向布局不同

    我们知道ipad全屏幕显示时,无论水平放置还是竖直放置,width 和 height 都是 regular,不像iphone能够区别,那么就不能使用size class 布局不同的水平和垂直界面了吗? ...