pde*_*eva 27 java concurrency multithreading
如果我有这样的代码 -
long x;
x = 0xFFFFFFFFL;
Run Code Online (Sandbox Code Playgroud)
如果我在32位机器上运行此代码,它是否保证是原子的,或者读取x的不同线程是否可能获得不完整/垃圾值?
pol*_*nts 48
以下是简短摘要:
int,char,byte,short,boolean,float,读/写操作总是原子double和long,如果它们是volatile,读/写总是原子的因此,只有读/写可能不是原子的异常:
double和long,如果他们没有被宣布volatile,他们不保证是原子的因此,就读/写共享数据的原子性而言,您只需要制作volatile任何double或long.无论在实际实现中使用了多少位,其他所有内容都已保证是原子的.
以下是此处转载的相关部分,以供快速参考:
JLS 17.7非原子化处理
double和long一些实现可能发现将64位上的单个写操作
long或double值划分为相邻32位值上的两个写操作是方便的.为了效率,这种行为是特定于实现的; Java虚拟机可以原子地或分两部分自由地执行写入long和double值.出于Java编程语言内存模型的目的,对non
volatile long或doublevalue 的单个写入被视为两个单独的写入:每个32位半写一个.这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况.写入和读取volatile long以及double值始终是原子的.对引用的写入和读取始终是原子的,无论它们是实现为32位还是64位值.建议VM实现者尽可能避免拆分64位值.鼓励程序员将共享的64位值声明为
volatile或正确同步其程序以避免可能的复杂情况.
byte可以在没有邻居干扰的情况下更新volatile字段int i;,i++是不是原子!volatile long[]是volatile 对数组的引用longlong元素本身不volatileJava虚拟机规范的第8.4节规定,未声明为volatile的double或long被视为两个32位变量,用于加载,存储,读取和写入操作.
此外,没有定义编码方式和两个32位操作的顺序.
该规范确实鼓励实现使操作成为原子,但它们并不需要它.
如果变量是volatile,那么读/写保证是原子的,但如果变量是非易失性的则不是.
一些实现可能发现将64位长或双值上的单个写操作划分为相邻32位值上的两个写操作是方便的.为了效率,这种行为是特定于实现的; Java虚拟机可以原子地或分两部分对long和double值执行写入.
出于Java编程语言内存模型的目的,对非易失性long或double值的单次写入被视为两个单独的写入:每个32位半写一次.这可能导致线程从一次写入看到64位值的前32位,而从另一次写入看到第二次32位的情况.volatile和long值的写入和读取始终是原子的.
当多个线程在没有同步的情况下访问long值时,必须使用volatile以确保一个线程所做的更改对其他线程可见,并确保读/写是原子的.
| 归档时间: |
|
| 查看次数: |
6408 次 |
| 最近记录: |