84

What operations in Java are considered atomic?

Brian
  • 2,912
  • 2
  • 23
  • 36
robinmag
  • 15,600
  • 18
  • 51
  • 54

3 Answers3

104
  • all assignments of primitive types except for long and double
  • all assignments of references
  • all assignments of volatile variables
  • all operations of java.concurrent.Atomic* classes

and maybe something more. Look at the jls.

As noted in the comments, atomicity does not imply visibility. So while another thread is guaranteed not to see a partially written int, it may never see the new value.

The operations on long and double are on common 64 bit CPUs atomic as well, although there's no guarantee. See also this feature request.

maaartinus
  • 40,991
  • 25
  • 130
  • 292
  • 12
    Also, bear in mind that while the operations are atomic, the visibility of those operations might not be guaranteed in a multithreaded application unless special care is taken (the details here are *way* to intricate to describe in a comment..) – nos Jan 21 '11 at 08:33
  • 5
    `64 bit jvm, long and double assignments are also atomic.` Are you sure? I'd say they are for compiled code, but what about interpreted code? Probably you're right, but is there any guarantee? – maaartinus Jan 21 '11 at 12:35
  • 4
    The spec still doesn't mandate that 64-bit JVMs provide atomicity to long and double assignments. http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7 In its famous words, "this behavior is implementation specific". However, more likely than not, 64-bit VMs would implement it as an atomic operation. – sjlee Jan 21 '11 at 15:59
  • Are you sure that reference assignments are Atomic? If so, then why does the AtomicReference class exist? http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicReference.html – rfeak Jan 30 '11 at 03:35
  • 1
    IMHO, normal reference assignments are atomic, but AtomicReference offers more: compareAndSet and getAndSet, which is something you couldn't achieve otherwise without synchronization. – maaartinus Jan 31 '11 at 01:40
  • @maaartinus, I upvoted your answer. Thank you! I was not sure about all assignments of primitive types except for long and double – Maksim Dmitriev Feb 21 '13 at 07:59
  • For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write. Writes and reads of volatile long and double values are always atomic. Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf – Sergii Shevchyk Apr 10 '13 at 08:11
  • I would be interested in: *= /= %= += -= &= and |= are covered here. – peterk Jun 18 '13 at 13:42
  • @peterk: This makes no sense... atomicity deals with memory access. When you write `a *= b + c`, everything depends on where do the operands come from. Using of local variables you can reduce it all to assignments and computations with local variables. The former was dealt above, the latter is atomic as it deals with no memory. – maaartinus Jun 18 '13 at 21:27
  • Yes seems there is now low overhead atomic way top do the above other than by using the AtomicInteger ( a whole object plus fields ) and doing some real fenagleing – peterk Jun 19 '13 at 22:28
  • @peterk Yes, the only alternative is using `Unsafe`, which is rather unsafe and non-portable. There's a proposal to standardize such operations. – maaartinus Feb 06 '15 at 09:50
5

In Java, the reading and writing of 32-bit or smaller quantities are guaranteed to be atomic.
By atomic, we mean each action takes place in one step and cannot be interrupted. Thus, when we have multithreaded applications, the read and write operations are thread-safe and need not be made synchronized.

For example, the following code is thread safe:

public class ThreadSafe   
  {  
    private int x;  
    public void setX(int x)  
          {
           this.x = x;
           } 
  }
sgokhales
  • 49,762
  • 33
  • 123
  • 158
  • 5
    ..threadsafe in the sense that the value will always be exactly either the original value or the set value. Most up to date value still necessarily isn't visible to other threads due to the lack of "volatile" or "synchronized". – Mikko Wilkman Feb 01 '11 at 08:00
  • 1
    +1 to what @MikkoWilkman says. That piece of code should not be used since it is definitely not thread safe from a memory visibility perspective. – Knuckles the Echidna May 18 '16 at 16:20
0

It would seem that assignments of longs are atomic, based on this method in AtomicLong.java:

public final void set(long newValue) {
    value = newValue;
}

Note the absence of any synchronization.

Lyle Z
  • 1,089
  • 9
  • 7
  • 4
    Look at the declaration of `value`. It's `volatile`. – maaartinus Oct 18 '13 at 09:38
  • 2
    That `value` is `volatile` does not make the assignment of `value` atomic, it merely avoids "publishing" issues. – Lyle Z Nov 05 '13 at 15:56
  • 8
    It does both, see [JLS, section 17.7](http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7): Writes and reads of volatile long and double values are always atomic. – maaartinus Nov 05 '13 at 20:40
  • @LyleZ the most valuable comment in this thread, in my opinion. – stdout Apr 24 '16 at 14:22