理解发生在之前和同步 [英] Understanding happens-before and synchronization

查看:113
本文介绍了理解发生在之前和同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试理解Java 发生在订单之前的概念,并且有一些事情看起来很混乱。据我所知,之前发生的只是行动集上的一个订单,并没有提供有关实时执行订单的任何保证。实际上(强调我的):

I'm trying to understand Java happens-before order concept and there are a few things that seem very confusing. As far as I can tell, happens before is just an order on the set of actions and does not provide any guarantees about real-time execution order. Actually (emphasize mine):


应该注意的是,两个动作之间存在先发生关系
必然意味着他们必须在实施中按顺序获得
的位置。 如果重新排序产生
结果与合法执行一致,则不违法。

所以,它说的是,如果有两个动作 w (写)和 r (阅读) hb(w,r),而不是 r 可能 实际上在执行中 w 之前发生,但不能保证它会。读 r 也会出现写 w

So, all it says is that if there are two actions w (write) and r (read) such that hb(w, r), than r might actually happens before w in an execution, but there's no guarantee that it will. Also the write w is observed by the read r.

如何确定在运行时随后执行两个操作?例如:

How I can determine that two actions are performed subsequently in run-time? For instance:

public volatile int v;
public int c;

操作:

Thread A
v = 3;  //w

Thread B
c = v;  //r

这里我们有 hb(w,r)但这并不意味着 c 在分配后将包含值 3 。如何强制 c 分配3?是 同步订单 提供了这样的保证吗?

Here we have hb(w, r) but that doesn't mean that c will contain value 3 after assignment. How do I enforce that c is assigned with 3? Does synchronization order provide such guarantees?

推荐答案

当JLS说有些时候线程A中的事件X在线程B中的事件Y与关系之前建立,这并不意味着X将在Y之前发生。

When the JLS says that some event X in thread A establishes a happens before relationship with event Y in thread B, it does not mean that X will happen before Y.

这意味着 IF X发生在Y之前,然后两个线程将同意 X发生在Y之前。也就是说,两个线程都会看到程序的内存状态为与Y之前发生的X一致。

It means that IF X happens before Y, then both threads will agree that X happened before Y. That is to say, both threads will see the program's memory in a state that is consistent with X happening before Y.

这完全是关于内存的。线程通过共享内存进行通信,但是当系统中有多个CPU时,所有CPU都试图访问同一个内存系统,那么内存系统就成了瓶颈。因此,允许典型的多CPU计算机中的CPU延迟,重新排序和缓存内存操作,以加快速度。

It's all about memory. Threads communicate through shared memory, but when there are multiple CPUs in a system, all trying to access the same memory system, then the memory system becomes a bottleneck. Therefore, the CPUs in a typical multi-CPU computer are allowed to delay, re-order, and cache memory operations in order to speed things up.

这很有用线程不会彼此交互,但是当它们实际上想要交互时会导致问题:如果线程A将值存储到普通变量中,Java不保证何时(或者甚至 if )线程B将看到值的变化。

That works great when threads are not interacting with one another, but it causes problems when they actually do want to interact: If thread A stores a value into an ordinary variable, Java makes no guarantee about when (or even if) thread B will see the value change.

为了在重要时克服这个问题,Java为您提供了某些同步线程的方法。也就是说,让线程同意程序内存的状态。 volatile 关键字和 synchronized 关键字是在线程之间建立同步的两种方法。

In order to overcome that problem when it's important, Java gives you certain means of synchronizing threads. That is, getting the threads to agree on the state of the program's memory. The volatile keyword and the synchronized keyword are two means of establishing synchronization between threads.

我认为他们称之为之前发生的原因是为了强调关系的传递性:如果你能证明A发生在B之前,并且你可以证明B发生在C之前,然后根据JLS中规定的规则,你已经证明A发生在C之前。

I think the reason they called it "happens before" is to emphasize the transitive nature of the relationship: If you can prove that A happens before B, and you can prove that B happens before C, then according to the rules specified in the JLS, you have proved that A happens before C.

这篇关于理解发生在之前和同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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