内存一致性 - 发生在Java之前的关系之前 [英] Memory Consistency - happens-before relationship in Java

查看:103
本文介绍了内存一致性 - 发生在Java之前的关系之前的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读有关内存一致性错误的Java文档时。我找到与创建发生的两个动作相关的点 - 在关系之前:




  • 当语句调用 Thread时.start(),每个具有
    的语句在与该语句的关系发生之前还与
    执行的每个语句之间发生
    线。新线程可以看到导致创建
    新线程的代码的影响。


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




我无法理解他们的意思。如果有人用一个简单的例子解释它会很棒。

解决方案

现代CPU并不总是将数据写入内存中命令它已更新,例如,如果您运行伪代码(假设变量总是存储在内存中以简化);

  a = 1 
b = a + 1

... CPU可能写得很好 b 在将 a 写入内存之前到内存。只要你在一个线程中运行东西,这不是一个真正的问题,因为一旦完成赋值,运行上面代码的线程将永远不会看到任一变量的旧值。



多线程是另一回事,您认为以下代码会让另一个线程获取您繁重计算的值;

  a = heavy_computation()
b = DONE

...其他线程在做......

 重复b!= DONE 
没有

结果= a

问题是,在将结果存储到存储器之前,可以在内存中设置完成标志内存,所以其他线程可能会在将计算结果写入内存之前获取内存地址a的值。



同样的问题会 - if Thread.start Thread.join 没有发生之前保证 - 给你一个问题代码类似于lems;

  a = 1 
Thread.start newthread
...

newthread:
do_computation(a)

...自<$线程启动时,c $ c> a 可能没有存储到内存中的值。



因为你几乎总是希望新线程成为能够使用你在开始之前初始化的数据, Thread.start 有一个之前发生保证,即在调用<$ c之前已更新的数据$ c> Thread.start 保证可用于新线程。同样的事情适用于 Thread.join 其中新线程写入的数据保证在终止后加入它的线程可见。 / p>

它只是让线程更容易。


While reading Java docs on Memory Consistency errors. I find points related to two actions that creates happen - before relationship:

  • 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.

I am not able to understand their meaning. It would be great if someone explain it with a simple example.

解决方案

Modern CPUs don't always write data to memory in the order it was updated, for example if you run the pseudo code (assuming variables are always stored to memory here for simplicity);

a = 1
b = a + 1

...the CPU may very well write b to memory before it writes a to memory. This isn't really a problem as long as you run things in a single thread, since the thread running the code above will never see the old value of either variable once the assignments have been made.

Multi threading is another matter, you'd think the following code would let another thread pick up the value of your heavy computation;

a = heavy_computation()
b = DONE

...the other thread doing...

repeat while b != DONE
    nothing

result = a

The problem though is that the done flag may be set in memory before the result is stored to memory, so the other thread may pick up the value of memory address a before the computation result is written to memory.

The same problem would - if Thread.start and Thread.join didn't have a "happens before" guarantee - give you problems with code like;

a = 1
Thread.start newthread
...

newthread:
    do_computation(a)

...since a may not have a value stored to memory when the thread starts.

Since you almost always want the new thread to be able to use data you initialized before starting it, Thread.start has a "happens before" guarantee, that is, data that has been updated before calling Thread.start is guaranteed to be available to the new thread. The same thing goes for Thread.join where data written by the new thread is guaranteed to be visible to the thread that joins it after termination.

It just makes threading much easier.

这篇关于内存一致性 - 发生在Java之前的关系之前的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆