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)
因此赋值是原子的。当一个线程读取一个原语(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.