一句话警告:如果这里 有 答案,请指望其中有很多是错误的。我不打算发布详细信息的原因之一是,因为我很确定至少在某些方面 会
犯错。我的意思是,当我说每个认为自己可以回答这个问题的人实际上有足够的严谨性来解决这个问题时,对社区没有任何不尊重。(Joe
Duffy最近发现了一些让.NET内存模型感到惊讶的东西。如果他能弄错的话,像我们这样的凡人也可以。)
我将仅从一个方面提供一些见解,因为它常常被误解:
波动性和原子性之间是有区别的。人们通常认为原子写入是易失性的(即,如果写入是原子的,则无需担心内存模型)。这不是真的。
易变性是关于一个线程(在源代码中,从逻辑上来说)执行读取是否会“看到”另一线程所做的更改。
原子是关于是否有任何机会,如果一个变化 是 看到的,只有变化的部分可以看出。
例如,写入一个整数字段。保证是原子的,但不是易变的。这意味着如果有(从foo.x = 0开始):
Thread 1: foo.x = 257;Thread 2: int y = foo.x;
可能
y是0或257。由于原子性约束,不会是其他任何值(例如256或1)。但是,即使您知道在“挂墙时间”中在线程1中的代码之后执行的线程2中的代码,也可能存在奇数缓存,内存访问了“移动”等。使变量为
xvolatile将解决此问题。
我将剩下的工作交给真正的诚实至善专家。



