Is it correct to say that static
means one copy of the value for all objects and volatile
means one copy of the value for all threads?
Anyway a static
variable value is also going to be one value for all threads, then why should we go for volatile
?
volatile variable value access will be direct from main memory. It should be used only in multi-threading environment. static variable will be loaded one time. If its used in single thread environment, even if the copy of the variable will be updated and there will be no harm accessing it as there is only one thread.
Now if static variable is used in multi-threading environment then there will be issues if one expects desired result from it. As each thread has their own copy then any increment or decrement on static variable from one thread may not reflect in another thread.
if one expects desired results from static variable then use volatile with static in multi-threading then everything will be resolved.
Declaring a static variable in Java, means that there will be only one copy, no matter how many objects of the class are created. The variable will be accessible even with no
Objects
created at all. However, threads may have locally cached values of it.When a variable is volatile and not static, there will be one variable for each
Object
. So, on the surface it seems there is no difference from a normal variable but totally different from static. However, even withObject
fields, a thread may cache a variable value locally.This means that if two threads update a variable of the same Object concurrently, and the variable is not declared volatile, there could be a case in which one of the thread has in cache an old value.
Even if you access a static value through multiple threads, each thread can have its local cached copy! To avoid this you can declare the variable as static volatile and this will force the thread to read each time the global value.
However, volatile is not a substitute for proper synchronisation!
For instance:
Executing
concurrentMethodWrong
concurrently many times may lead to a final value of counter different from zero!To solve the problem, you have to implement a lock:
Or use the
AtomicInteger
class.Difference Between Static and Volatile :
Static Variable: If two Threads(suppose
t1
andt2
) are accessing the same object and updating a variable which is declared as static then it meanst1
andt2
can make their own local copy of the same object(including static variables) in their respective cache, so update made byt1
to the static variable in its local cache wont reflect in the static variable fort2
cache .Static variables are used in the context of Object where update made by one object would reflect in all the other objects of the same class but not in the context of Thread where update of one thread to the static variable will reflect the changes immediately to all the threads (in their local cache).
Volatile variable: If two Threads(suppose
t1
andt2
) are accessing the same object and updating a variable which is declared as volatile then it meanst1
andt2
can make their own local cache of the Object except the variable which is declared as a volatile . So the volatile variable will have only one main copy which will be updated by different threads and update made by one thread to the volatile variable will immediately reflect to the other Thread.In addition to other answers, I would like to add one image for it(pic makes easy to understand)
static
variables may be cached for individual threads. In multi threaded environment if one thread modifies it's cached data, that may not reflect for other threads as they have a copy of it.volatile
declaration makes sure that threads won't cache the data and uses the shared copy only.image source
In simple terms,
static :
static
variables are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memoryvolatile: This keyword is applicable to both class and instance variables.
Have a look at this article by
Javin Paul
to understand volatile variables in a better way.In absence of
volatile
keyword, the value of variable in each thread's stack may be different. By making the variable asvolatile
, all threads will get same value in their working memory and memory consistency errors have been avoided.Here the term
variable
can be eitherstatic
(class) variable orinstance
(object) variable.Regarding your query :
If I need
instance
variable in my application, I can't usestatic
variable. Even in case ofstatic
variable, consistency is not guaranteed due to Thread cache as shown in the diagram.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.Using simple atomic variable access is more efficient than accessing these variables through synchronized code
Some of the classes in the
java.util.concurrent
package provide atomic methods that do not rely on synchronization.Refer to this high level concurrency control article for more details.
Especially have a look at Atomic variables.
Related SE questions:
Volatile Vs Atomic
Volatile boolean vs AtomicBoolean
Difference between volatile and synchronized in Java
If we declare a variable as static, there will be only one copy of the variable. So, whenever different threads access that variable, there will be only one final value for the variable(since there is only one memory location allocated for the variable).
If a variable is declared as volatile, all threads will have their own copy of the variable but the value is taken from the main memory.So, the value of the variable in all the threads will be the same.
So, in both cases, the main point is that the value of the variable is same across all threads.