这是简短的摘要:
- 对于参考,读/写 总是 原子的(即使在64位实现中也是如此!)
- 对于
int
,char
,byte
,short
,boolean
,float
,读/写操作 总是 原子 - 对于
double
和long
,如果它们是volatile
,则读/写 总是 原子的
因此,只有在读/写可能不是原子的情况下例外:
- 对于
double
和long
,如果他们 不 申报volatile
,他们 不能保证 是原子
所以,只要读原子/写入共享数据而言,你只需要做出
volatile的任何
double或
long。不管实际实现中使用了多少位,其他所有内容都已经保证是原子性的。
关于规格
这里是相关部分,此处转载以供快速参考:
[的JLS
17.7非原子处理
double和long](http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7)一些实现可能会发现将64位
long或double值的单个写操作分为相邻32位值的两个写操作很方便。为了提高效率,此行为是特定于实现的;Java虚拟机可以自由地执行原子和两部分的写入long和double值。出于Java编程语言内存模型的目的,一次对non-
volatilelong或doublevalue的写操作被视为两次单独的写操作:一个写给每个32位的一半。这可能导致线程从一次写入中看到64位值的前32位,而从另一次写入中看到后32位的情况。写和读的volatilelong和double值始终原子。引用的写入和读取始终是原子的,无论它们是实现为32位还是64位值。鼓励VM实现者避免在可能的情况下拆分其64位值。鼓励程序员将共享的64位值声明为
volatile或正确同步其程序,以避免可能的复杂性。
也可以看看
- JLS 17.6单词撕裂 -保证例如a
byte
可以在没有邻居干扰的情况下进行更新 - JLS 8.3.1.4
volatile
字段 - Java教程/基本类/并发/原子变量
- 需要注意的是给予
int i;
,i++
是 不是 原子!
- 需要注意的是给予



