问题
These are two atomic operations:
int value = 5;
Object obj = new Object();
But when using a primitive as a method parameter, would this be considered as an atomic operation:
public void setValue(int val, Object obj){
this.value = val; // Atomic?
this.obj = obj; // Not atomic?
}
? The copy of the object reference is not atomic since it includes a read and a write, right?
Would it be correct to say that the only way to make an atomic operation on an object reference is to declare it null or assign a new object to it, like:
Object obj = null;
and
Object obj = new Object();
?
回答1:
If the parameter in the above method was a reference to an object, then the operation would not be atomic, right?
In general this is correct. A good rule of thumb is to consider there is no atomicity at all, even with primitives like:
int b,c;
int a = ++b - c;
only primitives, but the whole assignment is potential not atomic.
If you need enshure atomic operations you have diferent posibilities:
- synchronised blocks
- immutable objects
- specific libraries (java.util.concurrent.atomic)
回答2:
When a thread reads the value of a primitive (except long and double), or of an object reference, it sees the value it has set in this variable, or the value that another thread has set in this variable.
However, although assigning a value to a shared variable in one thread is atomic, this doesn't mean that all the other threads will see the new value right after. To do that, the variable should be declared volatile. volatile also makes writes to long and double atomic. I prefer using AtomicXxx (AtomicLong, AtomicBoolean, etc.) in this case, though.
And if you want to atomically change the values of two shared variables, then you should synchronize every access (read and write) to these variables using a unique lock.
Moreover, every "check then act" or "read then write" operation is non-atomic. This means that these operations need synchronization as well:
a++; // read a, increment value, write value to a
if (a > 0) {a = b;} // check value of a, then assign new value to a.
Every single operation in your question is atomic. But in setValue()
, you have two atomic operations. The whole setValue
call is not atomic.
回答3:
To the JLS!
When a thread uses the value of a variable, the value it obtains is in fact a value stored into the variable by that thread or by some other thread. This is true even if the program does not contain code for proper synchronization. For example, if two threads store references to different objects into the same reference value, the variable will subsequently contain a reference to one object or the other, not a reference to some other object or a corrupted reference value.
So the assignment is atomic.
回答4:
public synchronized void setValue(int val, Object obj)
now the entire function is "atomic" which term I have not seen used in Java
来源:https://stackoverflow.com/questions/8076215/what-is-atomic