Is a volatile int in Java thread-safe?

JavaMultithreadingThread SafetyVolatile

Java Problem Overview


Is a volatile int in Java thread-safe? That is, can it be safely read from and written to without locking?

Java Solutions


Solution 1 - Java

Yes, you can read from it and write to it safely - but you can't do anything compound such as incrementing it safely, as that's a read/modify/write cycle. There's also the matter of how it interacts with access to other variables.

The precise nature of volatile is frankly confusing (see the memory model section of the JLS for more details) - I would personally generally use AtomicInteger instead, as a simpler way of making sure I get it right.

Solution 2 - Java

> [...] as in being able to be safely read from and written to without locking?

Yes, a read will always result in the value of the last write, (and both reads and writes are atomic operations).

A volatile read / write introduces a so called happens-before relation in the execution.

From the Java Language Specification Chapter 17: Threads and Locks

> A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.

In other words, when dealing with volatile variables you don't have to explicitly synchronize (introduce a happens-before relation) using synchronized keyword in order to ensure that the thread gets the latest value written to the variable.

As Jon Skeet points out though, the use of volatile variables are limited, and you should in general consider using classes from the java.util.concurrent package instead.

Solution 3 - Java

Access to volatile int in Java will be thread-safe. When I say access I mean the unit operation over it, like volatile_var = 10 or int temp = volatile_var (basically write/read with constant values). Volatile keyword in java ensures two things :

  1. When reading you always get the value in main memory. Generally for optimization purposes JVM use registers or in more general terms local memory foe storing/access variables. So in multi-threaded environment each thread may see different copy of variable. But making it volatile makes sure that write to variable is flushed to main memory and read to it also happens from main memory and hence making sure that thread see at right copy of variable.
  2. Access to the volatile is automatically synchronized. So JVM ensures an ordering while read/write to the variable.

However Jon Skeet mentions rightly that in non atomic operations (volatile_var = volatile + 1) different threads may get unexpected result.

Solution 4 - Java

  1. If two threads are both reading and writing to a shared variable, then using the volatile keyword for that is not enough. You need to use a synchronized in that case to guarantee that the reading and writing of the variable is atomic. Reading or writing a volatile variable does not block threads reading or writing. For this to happen you must use the synchronized keyword around critical sections.

  2. As an alternative to a synchronized block you could also use one of the many atomic data types found in the java.util.concurrent package. For instance, the AtomicLong or AtomicReference or one of the others.

It's thread safe if you have one writer thread and multiple reader threads.

class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}

Note : If helper is immutable then no need of volatile keyword.Here singleton will work properly.

In case of counter which is being incremented by multiple threads (reading writing operation) will not give correct answer. This condition is also illustrated by race condition.

public class Counter{
private volatile int i;
public int increment(){
i++;
}
}

NOTE : Here volatile will not help.

Solution 5 - Java

Not always.

It's not thread safe if multiple threads are writing and reading the variable. It's thread safe if you have one writer thread and multiple reader threads.

If you are looking for Thread safely, use AtomicXXX classes

> A small toolkit of classes that support lock-free thread-safe programming on single variables. > > In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:

boolean compareAndSet(expectedValue, updateValue);

Refer to @teto answer in below post:

https://stackoverflow.com/questions/3786825/volatile-boolean-vs-atomicboolean

Solution 6 - Java

If a volatile is not dependent on any other volatile variable its thread safe for read operation. In case of write volatile does not guarantee thread safety.

Assume you have a variable i which is volatile and its value is dependent on another volatile variable say j. Now Thread-1 access variable j and increment it and is about to update it in main memory from CPU cache. In case the Thread-2 reads the
variable i before Thread-1 can actually update the j in main memory. The value of i will be as per the old value of j which would be incorrect. Its also called Dirty read.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionshawnView Question on Stackoverflow
Solution 1 - JavaJon SkeetView Answer on Stackoverflow
Solution 2 - JavaaioobeView Answer on Stackoverflow
Solution 3 - JavaSaurabhView Answer on Stackoverflow
Solution 4 - JavaRahul SaxenaView Answer on Stackoverflow
Solution 5 - JavaRavindra babuView Answer on Stackoverflow
Solution 6 - JavaAjay VermaView Answer on Stackoverflow