In Java, when we want to ensure that compiler should not do optimization by keeping a local copy of a variable, then we make the variable volatile. Using the variable as volatile ensures that the threads would not use a local copy of the variable but they would use the variable as it is stored in the main memory. But, does it mean that the volatile variable is thread-safe? Also how does it differ in case of a primitive type and in case we use a user defined object?
volatile means that the value will always be fresh; if another thread put a new object into the variable before you, you will see that object.
It does not change the behavior of the value; you cannot magically make an object thread-safe.
not at all,in fact,volatile means that's the value can be seen by another thread at once, but don't mean that it's thread safe, it's not thread safe.
you can see this: http://java.sun.com/docs/books/jls/third_edition/html/classes.html and find the keyworkd volatile Fields
another refer here : http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html
volatile variable ensures visiblity and is not atomic.
Volatile is usually most appropriate for 'simple' state. Ex. a boolean member variable that may be set to tell a worker thread to terminate.
value of volatile variable will never be stored thread locally.
all reads and writes go to main memory.
meaning of volatile is different depending on the version of Java (i.e till Java 1.4 and after Java5.0).
one more link about volatile
Related
I have two threads sharing the same variable of type boolean. I discovered that I have to use volatile to guarantee the value is always read from main memory. But now I want to get rid of this volatile identifier, how can I achieve that? Is it true that I easily can extract my boolean property into an object. As the reference to object never change the thread will always access the correct value from the main memory. Will this work?
I have to use volatile to guarantee the value is always read from
main memory
That is not how volatile work. volatile is used to build a happens-before relation ship:
This means that changes to a volatile variable are always visible to
other threads. What's more, 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.
—— From the doc.
But now I want to get rid of this volatile identifier, how can I
achieve that?
Like said in another answer, you can use AtomicBoolean. Or, add synchronized block around the code reading/writing this variable. Or use some other mechanism, as well as they can build a happens-before relation ship between reading and writing this varibale in different threads.
Is it true that I easily can extract my boolean property into an
object. As the reference to object never change the thread will always
access the correct value from the main memory. Will this work?
No. The reference do not change, this does not mean the fresh object is always visible to other reading threads after it is updated.
you can also use AtomicBoolean instead if you do not like the keyword - also this will allow write access to be thread safe too
If I have multiple threads accessing the same global variable, each thread can cache the value of this variable, and access this cached copy from now on. I can use volatile to prevent this from happening, for example:
volatile int i = 123;
My question is: what does this behavior called (the behavior that each thread creates its own "copy" of the variable)?
You could call it code optimisation, cpu optimisation, compiler optimisation. Using volatile also provides happens-before and happens-after guarantees.
Note: this optimisation can be done by the javac, the JIT or the CPU.
Esentially, volatile is used to indicate that a variable's value will be modified by different threads.
Declaring a volatile Java variable means:
The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory";
Access to the variable acts as though it is enclosed in a synchronized block, synchronized on itself.
This question already has answers here:
Are static variables shared between threads?
(7 answers)
Closed 7 years ago.
In a multithread program if we have a static variable then does each thread have its own copy of the variable and is the change made by one thread visible to the other in case of static variable ?? Please explain
All variables1 are shared between all threads.
Only code visibility is defined by the variable type (eg. static/member, public/private) - but not thread visibility. (The volatile modifier affects thread access but is often not sufficient by itself.)
Using correct synchronization (and/or volatile variables) is required for "thread-safe" access for variables, and all data that can be reached from such, that can be accessed by multiple threads. Without correct synchronization there is no guarantee that another thread will 'see' a change to a [static] variable.
1 It is possible to create ThreadLocal 'variables' (via an indirect object), but this should be a rare case.
In a multithread program if we have a static variable then does each thread have its own copy of the variable
No. If you need that, you can use a ThreadLocal
and is the change made by one thread visible to the other in case of static variable
Not immediately. Another thread might still have the old value cached. To guarantee that the change is visible to other threads, you have multiple options. You can use a lock, a synchronized block/method, make the variable volatile or use some existing thread-safe utility class like AtomicReference.
If multiple threads are accessing the same static variable, all threads can see the changes.
As a result, if multiple threads are accessing the same variable, you will need to use locks for the variable to be thread-safe.
Yes, Static variables are shared between threads unlike local variables.
For more reference : http://java67.blogspot.com/2012/11/what-is-static-class-variable-method.html
There is a classic example ----Producers and Consumers. This inspires us that ,if you want to find the variable's change in other thread ,you must consider each Thread's possession time in CPU. EX: The variable may be just changed in one thread,and the other thread don't hava the use of CPU.So it can't find the change.
Of course,you can use
synchronized
to limit the thread's behavior(when multithreading) that changes the static variable.But you must know cross use of CPU , that means you don't know multiple threads' running way if you don't define their priority clearly.
Is it safe to say that a ThreadLocal variable is conceptually the 'opposite' of a volatile variable in Java?
Because in the former, every thread will only read/updatea local copy of the variable. But in the latter, every thread will always see the latest value of the variable that is in main memory....no chance of seeing stale values.
Exactly but with a slight twist,
a ThreadLocal variable is a variable different for each thread
any other variable exists only once so common for each Thread using the same object, whether it is volatile or not.
Volatile however specifies some kind of thread read/write boundary so they must synchronize on the latest value written by any other thread. However using volatile does not ensure thread safety.
E.g. a increment method incrementing a volatile int might still generate duplicates. To be sure that works thread safe you must synchronize the method updating the volatile attributes!
check this for more detailed information: https://www.cs.umd.edu/users/pugh/java/memoryModel/jsr-133-faq.html
Say that I have a private variable and I have a setVariable() method for it which is synchronized, isn't it exactly the same as using volatile modifier?
No. Volatile means the variable isn't cached in any per-thread cache, and its value is always retrieved from main memory when needed. Synchronization means that those per-thread caches will be kept in sync at certain points. In theory, using a volatile variable can come with a great speed penalty if many threads need to read the value of the variable, but it is changed only rarely.
No, calling a synchronized getXXX/setXXX method is not the same as reading/writing to a volatile variable.
Multiple threads can concurrently read from or write to a volatile variable. But only one thread at a time can read from or write to a variable that is guarded by a synchronized block.
volatile variables are not synchronized (at least, not in the way synchronized stuff is synchronized). What volatile does is ensure that a variable is retrieved each time it's used (ie: it prevents certain kinds of optimization), and IIRC that it's read and written in the correct order. This could conceivably emulate some kinds of synchronization, but it can't work the same if your setter has to set more than one thing. (If you set two volatile variables, for example, there will be a point where one is set and the other isn't.)
Actually No.
volatile is actually weaker form of synchronization, when field is declared as a volatile the compiler and runtime understands that this variable is shared and operations on it shouldn't be reordered with other memory operations. Volatile variable aren't cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always return a recent write by any thread.
just an example :
First thread run :
while(stopped){
... do something
}
Second thread run :
stopped = true;
it's useful to declare stopped as a volatile boolean for the first thread to have a fresh value of it.
There is no any relation.
Basically
Volatile => it always retrieves parameter's latest value
Synchronized => it serves only 1 thread at the same time