The Java™ Tutorials — Concurrency :Memory Consistency Errors 内存一致性错误

The Java™ Tutorials — Concurrency :Memory Consistency Errors 内存一致性错误

原文地址:https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html

关键点

  • 内存一致性错误:指多个线程对同一个变量的读取之结果是不同的,常发生于非原子操作导致的一致性问题之中,如并发环境下对自增变量的读取。
  • 先行发生关系:一个保证,它可以让一个操作的效果对另一个可见
  • 拓展阅读:http://wiki.jikexueyuan.com/project/java-concurrency/happen-before.html
  • 线程启动规则:Thread 对象的 start()方法 happen—before 此线程的每一个动作。
  • 线程中断规则:对线程 interrupt()方法的调用 happen—before 发生于被中断线程的代码检测到中断时事件的发生。

全文翻译

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变量:

int counter = 0;

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

这个counter变量被两个线程,A和B,所共同使用。假设线程A对counter进行自增操作:

counter++;

Then, shortly afterwards, thread B prints out counter:

此后不久,线程B打印出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.

如果两个语句于同一个线程中执行,那我们完全可以断定打出的结果是1。但是,如果两个语句在不同的线程中执行,打印出的值却可能为0。因为无法保证线程A对counter的改变对线程B可见,除非开发者已经在两个语句间建立了一个“先行发生关系”。

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.

我们已经见到了两种可建立先行发生关系的操作。

  • 当一个语句调用了Thread.start方法时,每个和此语句有先行发生关系的语句,同样也会和任何由此新线程执行的语句间建立先行发生关系。代码的创建线程的效果对这个线程是可见的。
  • 当一个线程结束,并且是通过在另一个线程中调用Thread.join方法来结束时,这个所有由此结束线程执行的语句都和在成功join之后的所有语句间建立了先行发生关系。此线程中代码的效果现在对被join的线程可见。

For a list of actions that create happens-before relationships, refer to the Summary page of the java.util.concurrent package..

对于可创建先行发生关系操作的列表,请参阅java.util.concurrent包中的总结页。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值