在《Effective Java》一书中,它指出:
语言规范保证读写 变量是原子的,除非变量类型为long或double [JLS, 17.4.7]。
“原子”在Java编程或一般编程上下文中是什么意思?
在《Effective Java》一书中,它指出:
语言规范保证读写 变量是原子的,除非变量类型为long或double [JLS, 17.4.7]。
“原子”在Java编程或一般编程上下文中是什么意思?
当前回答
在Java中,除了long和double之外的所有类型的读写字段都是原子地发生的,如果字段是用volatile修饰符声明的,那么即使long和double也是原子地读写的。也就是说,我们得到了100%的结果,或者得到了100%的结果,在变量中也不可能有任何中间结果。
其他回答
简单地说,原子意味着操作要么完成,要么不完成。 其他线程或cpu不会在操作中间捕获它。
“原子操作”是指从所有其他线程的角度来看是瞬时的操作。当保证生效时,您不需要担心部分完成的操作。
这是“对系统的其余部分来说,似乎是瞬间发生的”,并且属于计算过程中的线性化范畴。进一步引用这篇链接文章:
原子性是与并发进程隔离的保证。 此外,原子操作通常具有成功或失败 定义-他们要么成功地改变了系统的状态, 或者没有明显的效果。
So, for instance, in the context of a database system, one can have 'atomic commits', meaning that you can push a changeset of updates to a relational database and those changes will either all be submitted, or none of them at all in the event of failure, in this way data does not become corrupt, and consequential of locks and/or queues, the next operation will be a different write or a read, but only after the fact. In the context of variables and threading this is much the same, applied to memory.
你的引用强调了这并不需要在所有情况下都是预期行为。
如果你有几个线程执行下面代码中的方法m1和m2:
class SomeClass {
private int i = 0;
public void m1() { i = 5; }
public int m2() { return i; }
}
你可以保证任何调用m2的线程读0或5。
另一方面,对于下面的代码(其中i是长):
class SomeClass {
private long i = 0;
public void m1() { i = 1234567890L; }
public long m2() { return i; }
}
调用m2的线程可以读取0、1234567890L或其他一些随机值,因为语句i = 1234567890L不能保证长时间都是原子的(JVM可以在两次操作中写入前32位和后32位,线程可能会在中间观察到i)。
在Java中,除了long和double之外的所有类型的读写字段都是原子地发生的,如果字段是用volatile修饰符声明的,那么即使long和double也是原子地读写的。也就是说,我们得到了100%的结果,或者得到了100%的结果,在变量中也不可能有任何中间结果。