Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java volatile and atomic operations

farenda 2015-11-23 0

Problem:

How to use Java volatile and atomic operations to write lock-free code? These are two fundamental concepts in Java concurrency and understanding both of them is required to write correct, thread-safe code.

Solution:

Atomic

Atomic operation in Java is an operation that is guaranteed to not be interrupted in between by the thread scheduler. The following example shows an assignment that may be interrupted by the Thread Scheduler to execute other threads:

public class NotAtomicOperations {

   private long number;

   public void setNumber(long newNumber) {
       // This assignment may be split into two 32-bit operations,
       // between which Thread Scheduler may execute other thread!
       number = newNumber;
   }
}

What operations are atomic? Basically only read and write operations of:

  • all basic types except 64-bit types, namely long and double,
  • references variables (no matter whether it is 32-bit or 64-bit JVM),
  • all variables declared as volatile (including long and double).

Note: only read and write means that, for example, incrementation (++ operator) is not atomic and you cannot compare and set an int as one atomic operation.

volatile

Even though some operations are atomic, it doesn’t mean that their results will be immediately visible by all threads on multiprocessor or multi-core machines (which are standard these days). JVM doesn’t guarantee that and such results may be stored in a processor’s cache to which, threads running on other processors, don’t have access. The purpose of volatile keyword is to make those results visible in main memory, hence for all threads, like so:

public class VolatileVisibleToAllThreads {

   // volatile makes it visible to all threads!
   private volatile boolean running = true;

   public void stop() {
       // Simple write is atomic:
       running = false;
   }

   public boolean doWork() {
       // Will see the result of stop() called by other thread:
       while (running) {
           // doing some work...
       }
   }
}

Note: It is important to remember that volatile keyword can be used with only one variable. It doesn’t make sense to use it with more that one, because a thread can do only one atomic operation, without synchronization. So the following code won’t work correctly:

public class DoubleVolatileNotAtomic {

   private volatile int number1;
   private volatile int number2;

   public boolean setNumbers(int a, int b) {
       // Thread Scheduler may interrupt in between:
       number1 = a;
       number2 = b;
   }
}

Also adding volatile to long and double makes them atomic too:

public class VolatileWithAtomicLong {

   private volatile long number;

   public void setNumber(long newNumber) {
       // This assignment won't will be atomic thanks to volatile:
       number = newNumber;
   }
}

synchronized

In previous posts (e.g. synchronized method and synchronized object) we’ve shown how to use synchronized keyword to make the code thread-safe. One great feature of synchronized is that is makes operations on variables atomic and visible to other threads at the same time. What’s more, it allows to do atomic operations on more than one variable.

To summarize: atomic variables allow to write lock-free code, but its very easy to do it incorrectly, therefore synchronized is preferred in most cases.

Share with the World!
Categories Java Tags java, java-concurrency
Previous: Git Cheat Sheet
Next: Java Atomic Example

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored