What operations in Java are considered atomic?

28,623

Solution 1

  • 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.

Solution 2

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;
           } 
  }
Share:
28,623
robinmag
Author by

robinmag

Updated on April 25, 2020

Comments

  • robinmag
    robinmag about 4 years

    What operations in Java are considered atomic?

  • nos
    nos over 13 years
    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..)
  • maaartinus
    maaartinus over 13 years
    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?
  • sjlee
    sjlee over 13 years
    The spec still doesn't mandate that 64-bit JVMs provide atomicity to long and double assignments. java.sun.com/docs/books/jls/third_edition/html/memory.html#1‌​7.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.
  • rfeak
    rfeak over 13 years
    Are you sure that reference assignments are Atomic? If so, then why does the AtomicReference class exist? download.oracle.com/javase/1.5.0/docs/api/java/util/concurre‌​nt/…
  • maaartinus
    maaartinus over 13 years
    IMHO, normal reference assignments are atomic, but AtomicReference offers more: compareAndSet and getAndSet, which is something you couldn't achieve otherwise without synchronization.
  • Mikko Wilkman
    Mikko Wilkman over 13 years
    ..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".
  • Maksim Dmitriev
    Maksim Dmitriev about 11 years
    @maaartinus, I upvoted your answer. Thank you! I was not sure about all assignments of primitive types except for long and double
  • Sergii Shevchyk
    Sergii Shevchyk about 11 years
    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 docs.oracle.com/javase/specs/jls/se7/jls7.pdf
  • peterk
    peterk almost 11 years
    I would be interested in: *= /= %= += -= &= and |= are covered here.
  • maaartinus
    maaartinus almost 11 years
    @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.
  • peterk
    peterk almost 11 years
    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
  • maaartinus
    maaartinus over 10 years
    Look at the declaration of value. It's volatile.
  • Lyle Z
    Lyle Z over 10 years
    That value is volatile does not make the assignment of value atomic, it merely avoids "publishing" issues.
  • maaartinus
    maaartinus over 10 years
    It does both, see JLS, section 17.7: Writes and reads of volatile long and double values are always atomic.
  • maaartinus
    maaartinus over 9 years
    @peterk Yes, the only alternative is using Unsafe, which is rather unsafe and non-portable. There's a proposal to standardize such operations.
  • stdout
    stdout about 8 years
    @LyleZ the most valuable comment in this thread, in my opinion.
  • Knuckles the Echidna
    Knuckles the Echidna almost 8 years
    +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.