且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java内存模型 - 有人可以解释一下吗?

更新时间:2023-11-09 22:59:58

我不会试图真正回答您的问题在这里 - 而我会重定向到我看到的建议就这一主题的书: Java Concurrency in Practice

I'm not going to attempt to actually answer your questions here - instead I'll redirect you to the book which I seeing recommended for advice on this topic: Java Concurrency in Practice.

一个警告字句:如果的答案在这里,是错的。我不打算张贴细节的原因之一是因为我确定至少在某些方面错误。我的意思是没有对社会的任何不尊重,当我说,每个人,认为他们可以回答这个问题的机会实际上有足够的严格来正确的机会几乎为零。 (Joe Duffy最近发现了一个很惊讶的.NET内存模型,如果他可以错了,那么像我们这样的凡人。)

One word of warning: if there are answers here, expect quite a few of them to be wrong. One of the reasons I'm not going to post details is because I'm pretty sure I'd get it wrong in at least some respects. I mean no disrespect whatsoever to the community when I say that the chances of everyone who thinks they can answer this question actually having enough rigour to get it right is practically zero. (Joe Duffy recently found a bit of the .NET memory model that was surprised by. If he can get it wrong, so can mortals like us.)

我会在一个方面提供一些见解,因为它经常被误解:

I will offer some insight on just one aspect, because it's often misunderstood:

波动性和原子性之间有区别。人们经常认为原子写是易变的(即如果写是原子的,你不需要担心内存模型)。这不是真的。

There's a difference between volatility and atomicity. People often think that an atomic write is volatile (i.e. you don't need to worry about the memory model if the write is atomic). That's not true.

波动性是关于一个线程是否执行读取(在源代码中的逻辑)将看到另一个线程做出的更改。

Volatility is about whether one thread performing a read (logically, in the source code) will "see" changes made by another thread.

原子性是关于是否有任何机会,如果看到变化,只会看到一部分变化。

Atomicity is about whether there is any chance that if a change is seen, only part of the change will be seen.

例如,写一个整数字段。这保证是原子的,但不是易变的。这意味着如果我们有(从foo.x = 0开始):

For instance, take writing to an integer field. That is guaranteed to be atomic, but not volatile. That means that if we have (starting at foo.x = 0):

Thread 1: foo.x = 257;
Thread 2: int y = foo.x;

y 可能为0由于原子性约束,它不会是任何其他值(例如256或1)。然而,即使你知道在wall time中,线程2中的代码在线程1中的代码之后执行,可能存在奇数缓存,内存访问移动等。使变量 x volatile会解决这个问题。

It's possible for y to be 0 or 257. It won't be any other value, (e.g. 256 or 1) due to the atomicity constraint. However, even if you know that in "wall time" the code in thread 2 executed after the code in thread 1, there could be odd caching, memory accesses "moving" etc. Making the variable x volatile will fix this.

我会把余下的留给真正的诚实专家。

I'll leave the rest up to real honest-to-goodness experts.