Question

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();

?

Was it helpful?

Solution

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)

OTHER TIPS

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.

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.

public synchronized void setValue(int val, Object obj)

now the entire function is "atomic" which term I have not seen used in Java

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top