When exactly do you use the volatile keyword in Java? [duplicate] - java

This question already has answers here:
What is the volatile keyword useful for?
(25 answers)
What is the "volatile" keyword used for?
(8 answers)
Closed 3 years ago.
I have read "When to use 'volatile' in Java?" but I'm still confused. How do I know when I should mark a variable volatile? What if I get it wrong, either omitting a volatile on something that needs it or putting volatile on something that doesn't? What are the rules of thumb when figuring out what variables should be volatile in multithreaded code?

You basically use it when you want to let a member variable be accessed by multiple threads but do not need compound atomicity (not sure if this is the right terminology).
class BadExample {
private volatile int counter;
public void hit(){
/* This operation is in fact two operations:
* 1) int tmp = this.counter;
* 2) this.counter = tmp + 1;
* and is thus broken (counter becomes fewer
* than the accurate amount).
*/
counter++;
}
}
the above is a bad example, because you need compound atomicity.
class BadExampleFixed {
private int counter;
public synchronized void hit(){
/*
* Only one thread performs action (1), (2) at a time
* "atomically", in the sense that other threads can not
* observe the intermediate state between (1) and (2).
* Therefore, the counter will be accurate.
*/
counter++;
}
}
Now to a valid example:
class GoodExample {
private static volatile int temperature;
//Called by some other thread than main
public static void todaysTemperature(int temp){
// This operation is a single operation, so you
// do not need compound atomicity
temperature = temp;
}
public static void main(String[] args) throws Exception{
while(true){
Thread.sleep(2000);
System.out.println("Today's temperature is "+temperature);
}
}
}
Now, why can't you just use private static int temperature? In fact you can (in the sense that that your program won't blow up or something), but the change to temperature by the other thread may or may not be "visible" to the main thread.
Basically this means that it is even possible that your app. keeps writing Today's temperature is 0 forever if you don't use volatile (in practice, the value tends to become eventually visible. However, you should not risk not using volatile when necessary, since it can lead to nasty bugs (caused by in-completely constructed objects etc.).
If you put volatile keyword on something that doesn't need volatile, it won't affect your code's correctness (i.e. the behaviour will not change). In terms of performance, it will depend on the JVM implementation. In theory you might get a tiny performance degradation because the compiler can't do reordering optimisations, have to invalidate CPU cache etc., but then again the compiler could prove that your field cannot ever be accessed by multiple threads and remove the effect of volatile keyword completely and compile it to identical instructions.
EDIT:
Response to this comment:
Ok, but why can't we make todaysTemperature synchronized and create a synchronized getter for temperature?
You can and it will behave correctly. Anything that you can with volatile can be done with synchronized, but not vice versa. There are two reasons you might prefer volatile if you can:
Less bug prone: This depends on the context, but in many cases using volatile is less prone to concurrency bugs, like blocking while holding the lock, deadlocks etc.
More performant: In most JVM implementations, volatile can have significantly higher throughput and better latency. However in most applications the difference is too small to matter.

Volatile is most useful in lock-free algorithms. You mark the variable holding shared data as volatile when you are not using locking to access that variable and you want changes made by one thread to be visible in another, or you want to create a "happens-after" relation to ensure that computation is not re-ordered, again, to ensure changes become visible at the appropriate time.
The JMM Cookbook describes which operations can be re-ordered and which cannot.

volatile keyword guarantees that value of the volatile variable will always be read from main memory and not from Thread's local cache.
From java concurrency tutorial :
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
This means that changes to a volatile variable are always visible to other threads. It also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
Regarding your query:
How do I know when I should mark a variable volatile? What are the rules of thumb when figuring out what variables should be volatile in multithreaded code?
If you feel that all reader threads always get latest value of a variable, you have to mark variable as volatile
If you have one writer thread to modify the value of variable and multiple reader threads to read the value of variable, volatile modifier guarantees memory consistency.
If you have multiple threads to write and read variables, volatile modifier alone does not guaranty memory consistency. You have to synchronize the code or use high level concurrency constructs like Locks, Concurrent Collections, Atomic variables etc.
Related SE questions/articles:
Volatile variable explanation in Java docs
Difference between volatile and synchronized in Java
javarevisited article

The volatile can also be used to safely publish immutable objects in a multi-threaded Environment.
Declaring a field like public volatile ImmutableObject foo secures that all threads always see the currently available instance reference.
See Java Concurrency in Practice for more on that topic.

Actually disagree with the example given in the top voted answer, to my knowledge it does NOT properly illustrate volatile semantics as per the Java memory model. Volatile has way more complex semantics.
In the example provided, the main thread could continue to print "Today's temperature is 0" forever even if there is another thread running that is supposed to update the temperature if that other thread never gets scheduled.
A better way to illustrate volatile semantics is with 2 variables.
For simplicity's sake, we will assume that the only way to update the two variables is through the method "setTemperatures".
For simplicity's sake, we will assume that only 2 threads are running, main thread and thread 2.
//volatile variable
private static volatile int temperature;
//any other variable, could be volatile or not volatile doesnt matter.
private static int yesterdaysTemperature
//Called by other thread(s)
public static void setTemperatures(int temp, int yestemp){
//thread updates yesterday's temperature
yesterdaysTemperature = yestemp;
//thread updates today's temperature.
//This instruction can NOT be moved above the previous instruction for optimization.
temperature = temp;
}
the last two assignment instructions can NOT be reordered for optimization purposes by either the compiler, runtime or the hardware.
public static void main(String[] args) throws Exception{
while(true){
Thread.sleep(2000);
System.out.println("Today's temperature is "+temperature);
System.out.println("Yesterday's temperature was "+yesterdaysTemperature );
}
}
Once the main thread reads the volatile variable temperature (in the process of printing it),
1) There is a guarantee that it will see the most recently written value of this volatile variable regardless of how many threads are writing to it, regardless of which method they are updating it in, synchronized or not.
2) If the system.out statement in the main thread runs, after the time instant at which thread 2 has run the statement temperature = temp, both yesterday's temperature and todays temperature will be guaranteed to print the values set in them by thread 2 when it ran the statement temperature=temp.
This situation gets a LOT more complex if a) Multiple threads are running and b) There are other methods than just the setTemperatures method that can update the variable yesterday's temperature and todays temperature that are actively being called by these other threads. I think it would take a decent size article to analyze the implications based on how the Java Memory Model describes the volatile semantics.
In short, attempting to just use volatile for synchronization is extremely risky, and you would be better off sticking to synchronizing your methods.

http://mindprod.com/jgloss/volatile.html
"The volatile keyword is used on variables that may be modified simultaneously by other threads."
"Since other threads cannot see local variables, there is never any need to mark local variables volatile. You need synchronized to co-ordinate changes to variables from different threads, but often volatile will do just to look at them."

voltalie Means Keep changing value.The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory".In other words Java compiler and Thread that do not cache value of this variable and always read it from main memory.

Related

unsynchronized read/write of variables may cause data race?

in Java Performance Tuning by Jack Shirazi it writes:
This means that access and update of variables are automatically synchronized (as long as they are not longs or doubles). If a method consists solely of a variable access or assignment, there is no need to make it synchronized for thread safety, and every reason not to do so for performance. Thread safety extends further to any set of statements that are accessing or assigning to a variable independently of any other variable values.
according to the description above, operations like flag = true is always atomic and does not need synchronize.
However, here comes another article that regards the flollowing circumstance as data race:
class DataRaceExample {
static boolean flag = false;//w0
static void raiseFlag() {
flag = true;//w1
}
public static void main(String... args) {
ForkJoinPool.commonPool().execute(DataRaceExample::raiseFlag);
while (!flag);//r_i, where i ∈ [1, k), k may be infinite
System.out.print(flag);//r
}
}
and the author says:
Now, all executions have data races, because the flag is not volatile
It confused me a lot for the conflits between the two articles.
Jack Shirazi is wrong.
Access and update of a primitive variable such as int is atomic, but not synchronized.
Because it is atomic, it can be made fully thread-safe by making it volatile. Without that, other threads running on a different core may see stale values, because the CPU cache hasn't been refreshed.
The point that Jack Shirazi is trying to make is that non-volatile accesses to primitive types other than double and long are guaranteed to be performed atomically according to the JMM. Thus, synchronization is unnecessary to prevent, for example, torn reads and writes in the presence of concurrent accesses.
The confusion arises because his book predates JSR-133 and he uses terms like "automatically synchronized" which is not in line with modern notions of synchronization within the JMM.
In your second example, the loop will either not run or run forever.
The reason for this is that the variable flag is read just once when it is first checked.
If flag is volatile, then it is read from memory each time. This allows another thread to change the value of flag and the loop will see it.

Java - Multithreading - volatile [duplicate]

We use volatile in one of our projects to maintain the same copy of variable accessed by different threads. My question is whether it is alright to use volatile with static. The compiler does not give any errors but I don't understand the reason of using both.
Short of reading the memory model specification, I recommend you read http://jeremymanson.blogspot.com/2008/11/what-volatile-means-in-java.html. It's written by one of the JMM authors and should answer your question. Thinking of memory reads and writes in terms of the happens-before clause is also helpful; the JMM for Java 5 onwards adds happens-before semantics to volatile.
Specifically, when you read a volatile variable from one thread, all writes up to and including the write to that volatile variable from other threads are now visible to that one thread.
And, yes, you can use static with volatile. They do different things.
In Java, volatile has a similar general meaning as it does in C. The Java Memory Model (see the excellent link in ide's answer) allows threads to "see" a different value at the same time for variables marked as non-volatile. For example:
Thread a:
n = 1;
// wait...
n = 2;
Threads B and C:
while (true) {
System.out.println(name + ": " + n);
}
This output is allowed to happen (note that you're not guaranteed to strictly alternate between B and C, I'm just trying to show the "changeover" of B and C here):
C: 1
B: 1
C: 2
B: 1
C: 2
B: 2
This is entirely separate from the lock taken by println; thread B is allowed to see n as 1 even after C finds out that it's 2. There are a variety of very good reasons for this that I can't pretend to fully understand, many pertaining to speed, and some pertaining to security.
If it's volatile, you're guaranteed (apart from the println's locking, which I'll ignore for the moment) that B and C will both "simultaneously" see the new value of B as soon as it is sent.
You can use volatile with static because they affect different things. volatile causes changes a variable to be "replicated" to all threads that use that variable before they use it, while static shares a single variable across all classes that use that variable. (This can be rather confusing to people new to threading in Java, because every Thread happens to be implemented as a class.)
volatile means that the variable changes at runtime and that the compiler should not cache its value for any reason.
This is only really a problem when sharing the variable amongst threads, you don't want a thread working with stale data, so the compiler should never cache the value of a volatile variable reference.
Consider a scenario when two thread (Thread1 and Thread2) are accessing same variable 'mObject' with value 1.
when a Thread1 runs, it doesn't expect other threads to modify the variable 'mObject'. In this scenario the Thread1 caches the variable 'mObject' with value 1.
And if the Thread2 modify the value of 'mObject' to 2, still the Thread1 would be refering the mObject value as 1 since it did caching.
To avoid this caching we should to declare the variable as
private volatile int mObject;
in this scenarion the Thread1 will be getting updated value of mObject
Small elaboration, but the volatile keyword isn't just for for memory visibility. Before Java ver 1.5 was released the volatile keyword declared that the field will get the most recent value of the object by hitting main memory each time for reads and flushing for writes.
In the latest Java versions, the volatile keyword says two very important things:
Don't worry about how but know that when reading a volatile field
you will always have the most up to date value.
A compiler cannot reorder a volatile read/write as to maintain program order.
Check it out for more Java volatile examples.
The Java volatile keyword is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache. The value of an attribute is not cached thread-locally, and is always read from the "main memory".
Overcoming the data inconsistency problem is the advantage but reading from and writing to main memory is more expensive than accessing the CPU cache. Hence, if there are no specific requirements it is never recommended to use volatile keywords.
class Test
{
static int var=5;
}
In the above example, assume that two threads are working on the same class. Both threads run on different processors where each thread has its local copy of var. If any thread modifies its value, the change will not reflect in the original one in the main memory. It leads to data inconsistency because the other thread is not aware of the modified value.
class Test
{
static volatile int var =5;
}
In the above example, the value of a volatile variable will never be stored in the cache. All read and write will be done from and to the main memory.

AtomicInteger and volatile [duplicate]

This question already has answers here:
What is the difference between atomic / volatile / synchronized?
(7 answers)
Closed 3 years ago.
I know volatile allows for visibility, AtomicInteger allows for atomicity.
So if I use a volatile AtomicInteger, does it mean I don't have to use any more synchronization mechanisms?
Eg.
class A {
private volatile AtomicInteger count;
void someMethod(){
// do something
if(count.get() < 10) {
count.incrementAndGet();
}
}
Is this threadsafe?
I believe that Atomic* actually gives both atomicity and volatility. So when you call (say) AtomicInteger.get(), you're guaranteed to get the latest value. This is documented in the java.util.concurrent.atomic package documentation:
The memory effects for accesses and updates of atomics generally follow the rules for volatiles, as stated in section 17.4 of The Java™ Language Specification.
get has the memory effects of reading a volatile variable.
set has the memory effects of writing (assigning) a volatile variable.
lazySet has the memory effects of writing (assigning) a volatile variable except that it permits reorderings with subsequent (but not previous) memory actions that do not themselves impose reordering constraints with ordinary non-volatile writes. Among other usage contexts, > - lazySet may apply when nulling out, for the sake of garbage collection, a reference that is never accessed again.
weakCompareAndSet atomically reads and conditionally writes a variable but does not create any happens-before orderings, so provides no guarantees with respect to previous or subsequent reads and writes of any variables other than the target of the weakCompareAndSet.
compareAndSet and all other read-and-update operations such as getAndIncrement have the memory effects of both reading and writing volatile variables.
Now if you have
volatile AtomicInteger count;
the volatile part means that each thread will use the latest AtomicInteger reference, and the fact that it's an AtomicInteger means that you'll also see the latest value for that object.
It's not common (IME) to need this - because normally you wouldn't reassign count to refer to a different object. Instead, you'd have:
private final AtomicInteger count = new AtomicInteger();
At that point, the fact that it's a final variable means that all threads will be dealing with the same object - and the fact that it's an Atomic* object means they'll see the latest value within that object.
I'd say no, it's not thread-safe, if you define thread-safe as having the same result under single threaded mode and multithreaded mode. In single threaded mode, the count will never go greater than 10, but in multithreaded mode it can.
The issue is that get and incrementAndGet is atomic but an if is not. Keep in mind that a non-atomic operation can be paused at any time. For example:
count = 9 currently.
Thread A runs if(count.get() <10) and gets true and stopped there.
Thread B runs if(count.get() <10) and gets true too so it runs count.incrementAndGet() and finishes. Now count = 10.
Thread A resumes and runs count.incrementAndGet(), now count = 11 which will never happen in single threaded mode.
If you want to make it thread-safe without using synchronized which is slower, try this implementation instead:
class A{
final AtomicInteger count;
void someMethod(){
// do something
if(count.getAndIncrement() <10){
// safe now
} else count.getAndDecrement(); // rollback so this thread did nothing to count
}
To maintain the original semantics, and support multiple threads, you could do something like:
public class A {
private AtomicInteger count = new AtomicInteger(0);
public void someMethod() {
int i = count.get();
while (i < 10 && !count.compareAndSet(i, i + 1)) {
i = count.get();
}
}
}
This avoids any thread ever seeing count reach 10.
Answer is there in this code
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/atomic/AtomicInteger.java
This is source code of AtomicInteger.
The value is Volatile.
So,AtomicInteger uses Volatile inside.
Your query can be answered in 2 parts, because there are 2 questions in your query :
1)
Referring to Oracle's tutorial documentation for Atomic variables :
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomicvars.html
The java.util.concurrent.atomic package defines classes that support atomic operations on single variables. All classes have get and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.
So atomic integer does use volatile inside, as other answers here have mentioned. So there's no point in making your atomic integer volatile. You need to synchronize your method.
You should watch John Purcell's free video on Udemy , where he shows the failure of volatile keyword when multiple threads are trying to modify it. Simple and beautiful example.
https://www.udemy.com/course/java-multithreading/learn/lecture/108950#overview
If you change the volatile counter in John's example into an atomic variable, his code is guaranteed to succeed without using sunchronized keyword like he has done in his tutorial
2) Coming to your code :
Say thread 1 kicks into action and "someMethod" does a get and checks for size. It is possible that before getAndIncrement executes(say, by thread 1) , another thread (say thread 2)kicks in and increases the count to 10, and gets out; after which, your thread 1 will resume and increase count to 11. This is erroneous output. This is because your "someMethod" is not protected in anyway from synhronization problems.
I would still recommend you to watch john purcell's videos to see where volatile fails , so that you have a better understanding of the keyword volatile. Replace it with atomicinteger in his example and see the magic.

volatile synchronized combination for performance

When Synchronization is used there is a performance impact. Can volatile be used in combination with synchronized to reduce the performance overhead ? For example, instance of Counter will be shared among many threads and each thread can access Counter's public methods. In the below code volatile is used for getter and synchronized is used for setter
public class Counter
{
private volatile int count;
public Counter()
{
count = 0;
}
public int getCount()
{
return count;
}
public synchronized void increment()
{
++count;
}
}
Please let me know in which scenario this might break ?
Yes, you definitely can. In fact, if you look at the source code of AtomicInteger, it's essentially what they do. AtomicInteger.get simply returns value, which is a volatile int (link). The only real difference from what you've done and what they do is that they use a CAS for the increment instead of synchronization. On modern hardware, a CAS can eliminate any mutual exclusion; on older hardware, the JVM will put some sort of mutex around the increment.
Volatile reads are about as fast as non-volatile ones, so the reads will be quite fast.
Not only that, but volatile fields are guaranteed not to tear: see JLS 17.7, which specifies that volatile longs and doubles are not subject to word tearing. So your code would work with a long just as well as an int.
As Diego Frehner points out, you might not see the result of an increment if you get the value "right as" the increment happens -- you'll either see the before or the after. Of course, if get were synchronized you'd have exactly the same behavior from the read thread -- you'd either see the before-increment or post-increment value. So it's really the same either way. In other words, it doesn't make sense to say that you won't see the value as it's happening -- unless you meant word tearing, which (a) you won't get and (b) you would never want.
1. I have personally used this mechanism of volatile combined with synchronized.
2. You can alone use synchronized, and you will always get a consistent result, but using
only volatile alone will Not yield the same result always.
3. This is because volatile keyword is not a synchronization primitive. It merely prevents caching of the value on the thread, but it does not prevent two threads from modifying the same value and writing it back concurrently.
4. volatile give concurrent access to threads without lock, but then using synchronized will allow only one thread to get access to this and all the synchronized methods in the class.
5. And using both volatile and synchronized will do this....
volatile - will reflect the changed values to thread, and prevent caching,
synchronized - But using synchronized keyword, will make sure that only one thread gets the access to the synchronized methods of the class.
You will not always get the most actual count when calling getCount(). An AtomicInteger could be appropriate for you.
There wouldn't be a performance gain from using both. Volatile guarantees that the value of a variable will be consistent when reading/writing to the variable across threads executing in parallel by preventing caching. Synchronized, when applied to a method (as you do in your example), only allows a single thread to enter that method at a time and blocks others until execution is complete.

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.

Categories

Resources