Java 什么是原子?

Java 什么是原子?,java,terminology,atomicity,Java,Terminology,Atomicity,这是两种原子操作: int value = 5; Object obj = new Object(); 但当使用原语作为方法参数时,这是否会被视为原子操作: public void setValue(int val,Object obj){ this.value=val;//原子? this.obj=obj;//不是原子的? } ?? 对象引用的副本不是原子的,因为它包括读取和写入,对吗 对对象引用进行原子操作的唯一方法是将其声明为null或为其分配一个新对象,这样说是否正确,如: Obje

这是两种原子操作:

int value = 5;
Object obj = new Object();
但当使用原语作为方法参数时,这是否会被视为原子操作:

public void setValue(int val,Object obj){
this.value=val;//原子?
this.obj=obj;//不是原子的?
}

?? 对象引用的副本不是原子的,因为它包括读取和写入,对吗

对对象引用进行原子操作的唯一方法是将其声明为null或为其分配一个新对象,这样说是否正确,如:

Object obj = null;

?

如果上述方法中的参数是对对象的引用, 那么操作就不会是原子的了,对吧

一般来说,这是正确的。一个很好的经验法则是考虑根本没有原子性,即使有像:

这样的基元。
int b,c; 
int a = ++b - c;
只有原语,但整个赋值是潜在的而不是原子的

如果您需要enshure原子操作,您有不同的可能性:

  • 同步块
  • 不变对象
  • 特定库(java.util.concurrent.atomic)
现在,整个函数都是“原子的”,这是我在Java中没有见过的术语

当线程使用变量的值时,它获得的值实际上是该线程或其他线程存储在变量中的值。即使程序不包含正确同步的代码,这也是正确的。例如,如果两个线程将对不同对象的引用存储到同一个引用值中,则变量随后将包含对一个对象或另一个对象的引用,而不是对其他对象的引用或损坏的引用值


因此赋值是原子的。

当一个线程读取一个原语(long和double除外)或一个对象引用的值时,它会看到它在这个变量中设置的值,或者另一个线程在这个变量中设置的值

然而,尽管在一个线程中为共享变量赋值是原子性的,但这并不意味着所有其他线程都会立即看到新值。为此,应将变量声明为volatile。volatile还使写操作成为长的和双原子的。不过,我更喜欢在这种情况下使用AtomicXxx(AtomicLong、AtomicBoolean等)

如果您想自动更改两个共享变量的值,那么应该使用唯一锁同步对这些变量的每次访问(读写)

此外,每个“先检查后执行”或“先读后写”操作都是非原子操作。这意味着这些操作也需要同步:

a++; // read a, increment value, write value to a
if (a > 0) {a = b;} // check value of a, then assign new value to a.

你问题中的每一个操作都是原子的。但是在
setValue()
中,有两个原子操作。整个
setValue
调用不是原子的

谢谢你的回答!我还编辑了我的问题,因此它现在包含了一个在方法调用中使用对象引用时的代码示例。感谢您提到“之前发生”关系。
public synchronized void setValue(int val, Object obj)
a++; // read a, increment value, write value to a
if (a > 0) {a = b;} // check value of a, then assign new value to a.