2011-11-30 117 views
2

我在读“有效的Java第二版”由Joshua Bloch和即时通讯通过下面的语句混淆关于并发 -多个线程读取一个变量

“的语言规范gaurantees,阅读或写一个变量是原子,除非该变量的类型为long或double [JLS,14.4.7]换句话说,读取一个long或double以外的变量可以返回某个线程存储到该变量中的值,即使多线程修改该变量同时并且没有同步。“

这是在第259页的最后一段中陈述的,以防任何人手头有书。

即使多个线程正在修改它,所引用的变量是否也总是有值?

+1

4-4字节的原子读/写,它基本上意味着一个由2 x 4byte的位置组成的变量不能保证完全在一个完整的书面或阅读状态。 –

回答

2

你必须阅读整个句子。在这里,让我为你重新编写它:

“换句话说,即使多个线程修改了变量,读取一个long或double以外的变量也会返回一个由某个线程存储到该变量中的值同时,没有同步“

变为:

”让我们假设变量不是长或双(因为当时特殊的规定),即使有多个线程同时修改变量而没。同步来保护它,那么一个变量将总是有一个值。

此值将始终是其中一个线程写入的值之一。你将无法提前知道哪一个,但这总是其中一个人写的价值。 “

0

他说变量将有一个值,但该值是非确定性的(由于您的并发线程对变量的操作)。

1

如果你有多个线程写入和读取/从一个双或长没有附加volatile关键字。读取可能会获得以前从未写入的值。

原因是这些是8字节长而不是4字节长,所以你可以读取一半的变量的新值和另一半的旧值(可能不是这么简单的基于特定的体系结构,但这是这个想法),导致写入它的从不不正确的读取。