Can using volatile with "AtomicInteger" guarantees thread safety? [duplicate] - java

This question already has answers here:
What is the difference between atomic / volatile / synchronized?
(7 answers)
Closed 3 years ago.
Suppose I have
private volatile AtomicInteger atomInt = new AtomicInteger(3);
and in methods my usage is atomInt.incrementAndGet().
Since I am using AtomicInteger, it will avoid "thread interference". And then I am using volatile, so it will guarantee the consistent view of the variable across all threads. Does it mean that I have got complete thread safety or still there are chances of "memory consistency issues"?
I got confused because of usage of "reduce" in tutorial, so it suggests me that there are still chances but I cannot think of it:
Using volatile variables reduces the risk of memory consistency
errors, because any write to a volatile variable establishes a
happens-before relationship with subsequent reads of that same
variable.

And then I am using volatile, so it will guarantee the consistent view of the variable across all threads.
Thread-safety is already guaranteed by atomic variables. volatile is redundant if you won't reassign the variable. You can replace volatile with final here:
private final AtomicInteger atomInt = new AtomicInteger(3);
Does it mean that I have got complete thread safety or still there are chances of "memory consistency issues"?
At this moment, it's absolutely thread-safe. No "memory consistency issues" might happen with the variable. But using proper thread-safe components doesn't mean that the whole class/program is thread-safe. Problems might take place if interactions between them are incorrect.
Using volatile variables reduces the risk of memory consistency errors ...
volatile variables can only guarantee visibility. They don't guarantee atomicity.
As Brian Goetz writes (emphasis mine):
volatile variables are convenient, but they have limitations. The most common use for volatile variables is as a completion, interruption, or status flag. Volatile variables can be used for other kinds of state information, but more care is required when attempting this. For example, the semantics of volatile are not strong enough to make the increment operation (count++) atomic, unless you can guarantee that the variable is written only from a single thread.
You can use volatile variables only when all the following criteria are met:
Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;
The variable does not participate in invariants with other state variables;
Locking is not required for any other reason while the variable is being accessed.
From the docs of the java.util.concurrent.atomic package:
get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.

Volatile does mean that changes to the variable will be visible. But in this case you shouldn’t be changing the reference held by the variable.
It seems very odd that you’d want to make a reference to an Atomic object volatile. The whole point of the atomicinteger class is to provide a way to access and change an integer value safely. The only reason to make some variable volatile is because you intend to overwrite its value. Why overwrite the reference to the AtomicInteger when you can use its instance methods to update its value?
That’s why you are getting advice to make this variable final instead of volatile. Making the variable final nails down the reference so it can’t change, while making sure the reference contained by that variable is visible. The atomicInteger manages its own state in a threadsafe way so you shouldn’t have to overwrite the reference to it.
So it’s not exactly correct to say volatile is redundant here. But it is doing something that typically shouldn’t have to be done. Use volatile when you have to change the value contained in the variable. Use final when you shouldn’t be changing the value contained in the variable.

Related

Atomic variables over Volatile

Since Atomic variables are volatile, are there any disadvantages of using always using Atomic variable even if you just need the volatility aspect?
From a concurrency perspective there is no difference between:
final AtomicInteger foo1 = new AtomicInteger();
And
volatile int foo2;
A foo1.get/set is the same as reading of writing to the foo2. Both will provide atomicity, visibility and ordering guarantees. If you look in the code of e.g. AtomicInteger, you will see a volatile int variable.
The primary use-cases for an Atomic is that it is very easy to do read modify write operations like incrementing a counter. And that you have access to more relaxed forms of ordering like getRelease and setAcquire. But you can do the same thing using AtomicFieldReference and VarHandles (although the syntax is less pretty).
One drawback of atomic is extra memory usage and indirection.
A Variable cannot be atomic. There is a clear difference between Atomicity and Volatile nature.
Atomicity: If only one thread can execute a set of instruction at a given time, the operation is called Atomic.
Volatile: A volatile nature ensures visibility. If a thread modify some volatile state the other threads get most recent updated state.
Examples :
volatile boolean flag;
public void flipTheFlag(){
if(flag == true){
flag = false;
}else{
flag = true;
}
}
If multiple threads are working on operation flipTheFlag, the value of flag will be uncertain even though the flag is volatile variable. That's why operation flipTheFlag need to be Atomic. We can make the flipTheFlag operation atomic just by adding keyword 'synchronized'.
When after creation of the final Atomic object different threads use the object to change the internal state, everything works as if volatile.
However there is an extra object instance around. Costs memory and speed performance. It should in this case be constant/effectively final, and its creation should be done before an other thread will have access.
An other aspect - which correctness I actually do not remember from the java reference but did read elsewhere -, is that with several fields, when one field is volatile on its modification also the other fields will be updated for other threads.
Atomic constants (or similar constant arrays of 1 item) still have a mutable state and are sometimes abused to collect aggregated results with a Stream operation which can only access constants. This means Atomic does not imply a multithreading usage.
In x = x + c; (volatile x) you will read the latest x, but after adding c an other thread might change x and you still will assign a stale sum to x. Here atomicity is required. Or if (x > 0) x = c;.
So to answer the question: depending on the brittle context they are somewhat interchangeable. I can see why you prefer Atomic, but there are simple cases where volatile is considerably more performant, especially in fine grained concurrency.
A last remark: I am not totally confident, whether I am entirely correct here.

static variables in multithreading

I found that declaring a variable as static makes no sense in Multi-Threading. I assume that, this is because of every thread has its own stack. Is this the only reason?
I know that static variables should be used within synchronized block. but why?
static makes no sense in Multi-Threading.
Im afraid you are making the reverse statement. Static variable is a shared resource, which can be used to exchange some information among different threads. And we need to be careful while accessing such a shared resource. Hence, we need to make sure that the access to static variables in multi-threaded environment is synchronized.
every thread has its own stack
This is a correct statement. Each thread has its own stack but they share the process heap. Stack holds only the local variables and not the variables on the heap. Static variables are stored in the PermGen section of the heap and hence the access to them should be well guarded.
Because first part of question is already answered, I will try to answer on second question.
I know that static variables should be used within synchronized block. but why?
Because if you don't use atomic, operations with variables are not atomic. That's why you should block variables while working with them. But in real world, you can use volatile keyword, that will guarantee you, that threads will have actual values of variable.
If you change a variable in a multithreaded environment, the new value may not neccessarily visibile as it might be cached. This is also true for static variables of course. If you don't use a synchronized block you might consider using volatile instead. This will also guaruantee that the various threads get an updated copy, without the need of synchronizing.
Wether volatile is enough four your application depends on your requirements.
Add volatile to your static declaration.
volatile will guarantee any other thread will see the most recent value of the variable. So, with volatile it will make sense.
However, volatile will not guarantee atomicity. If you write to your variable from more than one thread you might want to use atomics or synchronize block.
I think volatile will be fine.

Why can an Object member variable not be both final and volatile in Java?

If in a class I have a ConcurrentHashMap instance that will be modified and read by multiple threads I might define like this:
public class My Class {
private volatile ConcurrentHashMap<String,String> myMap = new ConcurrentHashMap<String,String>();
...
}
adding final to the myMap field results in an error saying I can only use final or volatile. Why can it not be both?
volatile only has relevance to modifications of the variable itself, not the object it refers to. It makes no sense to have a final volatile field because final fields cannot be modified. Just declare the field final and it should be fine.
It's because of Java Memory Model (JMM).
Essentially, when you declare object field as final you need to initialize it in object's constructor and then final field won't change it's value. And JMM promises that after ctor is finished any thread will see the same (correct) value of final field. So, you won't need to use explicit synchronization, such as synchronize or Lock to allow all threads to see correct value of final field.
When you declare object's field as volatile, field's value can change, but still every read of value from any thread will see latest value written to it.
So, final and volatile achieve same purpose -- visibility of object's field value, but first is specifically used for a variable may only be assigned to once and second is used for a variable that can be changed many times.
References:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
Because volatile and final are two extreme ends in Java
volatile means the variable is bound to changes
final means the value of the variable will never change whatsoever
volatile is used for variables that their value may change, in certain cases, otherwise there is no need for volatile, and final means that the variable may not change, so there's no need for volatile.
Your concurrency concerns are important, but making the HashMap volatile will not solve the problem, for handling the concurrency issues, you already use ConcurrentHashMap.
A volatile field gives you guarantees as what happens when you change it. (No an object which it might be a reference to)
A final field cannot be changed (What the fields reference can be changed)
It makes no sense to have both.
volatile modifier guarantees that all reads and writes go straight to main memory, i.e. like the variable access is almost into synchronized block. This is irrelevant for final variable that cannot be changed.
Because it doesn't make any sense. Volatile affects object reference value, not the object's fields/etc.
In your situation (you have concurrent map) you should do the field final.
In a multithread environment different threads will read a variable from main memory and add it to the CPU cache. It may result in two different threads making changes on the same variable, while ignoring each others results.
enter image description here
We use word volatile to indicate that variable will be saved in main memory and will be read from main memory. Thus whenever a thread want to read/write a variable it will be done from main memory, essentially making a variable safe in multithread environment.
When we use final keyword we indicate that variable will not change. As you can see if a variable is unchangeable, than it doesn't matter if multiple threads will use it. No thread can change the variable, so even if variable is saved to CPU caches at different times, and threads will use this variable at different times than it's still ok, because the variable can only be read.

Is a volatile int in Java thread-safe?

Is a volatile int in Java thread-safe? That is, can it be safely read from and written to without locking?
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.
[...] 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.
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 :
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.
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.
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.
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:
Volatile boolean vs AtomicBoolean
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.

Java volatile modifier and synchronized blocks

Does a variable that is accessed by multiple threads, but only inside synchronized blocks, need the volatile modifier? If not, why?
You do not need to use volatile inside of synchronized, synchronized already guarantees the correct behavior for local caching of variables when used consistently (on every access).
volatile works on primitive values, and can be a nice shortcut for atomic accesses to a primitive type. Note that the behavior of volatile has changed in JDK 5 from 1.4.
More information can be found here
No. When you work within a synchronized block, all cached variables are synchronized on access, since it creates a memory barrier.
For details, see this comparison (with discussion) of volatile to synchronized.
Blocks that synchronize on the same object (or method) are guaranteed to not be run at the same time. So as long as you synchronize to the same object, your variable will never have concurrent accesses, so it doesn't need special treatment.
If your accesses aren't synchronized, then you have a race condition. Making the variable volatile can be correct for some primitive variables (I defer to other posts for better info on volaitle). If that isn't useful, you almost certainly have a bug.

Categories

Resources