275

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?

Paolo Forgia
  • 5,804
  • 7
  • 39
  • 55
Jothi
  • 13,342
  • 20
  • 59
  • 92
  • Official explanation of volatile: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#volatile – Vadzim Aug 03 '15 at 13:43

8 Answers8

375

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 with Object 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:

private static volatile int counter = 0;

private void concurrentMethodWrong() {
  counter = counter + 5;
  //do something
  counter = counter - 5;
}

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:

private static final Object counterLock = new Object();

private static volatile int counter = 0;

private void concurrentMethodRight() {
  synchronized (counterLock) {
    counter = counter + 5;
  }
  //do something
  synchronized (counterLock) {
    counter = counter - 5;
  }
}

Or use the AtomicInteger class.

ישו אוהב אותך
  • 22,515
  • 9
  • 59
  • 80
stivlo
  • 77,013
  • 31
  • 135
  • 193
  • So does it means ALWAYS it's necessary to set volatile? – Dr.jacky Nov 11 '12 at 08:34
  • 8
    The volatile modifier guarantees that any thread that reads a field will see the most recently written value, so it's necessary if the variable is shared among multiple thread and you need this feature, it depends on your use case. – stivlo Nov 11 '12 at 14:41
  • 5
    What is the cache when you say "locally cached"? CPU cache, some kind of JVM cache? – mert inan Dec 17 '12 at 21:15
  • 6
    @mertinan yes, the variable can be in a cache nearer to the processor or core. See http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html for more details. – stivlo Dec 17 '12 at 22:08
  • 18
    'volatile' does ***not*** imply 'one variable per object'. Absence of 'static' does that. -1 for failing to clear up this elementary misconception on the part of the OP. – user207421 Aug 25 '13 at 06:19
  • 27
    @EJP I thought that the sentence "Declaring a variable as volatile, there will be one variable for each Object. So on the surface it seems there is no difference from a normal variable" was explaining that, I've added *and not static*, feel free to edit the article and improve the wording to make that clearer. – stivlo Aug 25 '13 at 12:47
  • 1
    If volatile doesn't automatically impose proper synchronization then why use it? We could make any regular variable synchronized. What's the purpose of volatile? – ernesto Sep 15 '14 at 04:31
  • 1
    @stivlo I don't see how the counter can be different from zero. Each thread that calls the concurrentMethodWrong will increment and decrement by 5. So the effective work done by each thread is zero (0). Am I missing something fundamental in my reasoning? – filip Sep 15 '14 at 16:52
  • @stivlo I see, but I can't explain it. Well, guess I have to read these posts a few more times. – filip Sep 15 '14 at 19:48
  • 4
    @filip counter = counter + 5 is not an atomic operation. The thread could be switched in the middle of it, i.e. after reading counter but before adding 5. – stivlo Sep 15 '14 at 22:39
  • @stivlo Yes, of course. I get it know, thank you for your time. – filip Sep 16 '14 at 11:26
  • 4
    @ernesto volatile is sufficient if only one thread ever writes to the volatile variable. If two or more threads can write to it, then you need synchronized too. – John Hascall Apr 24 '15 at 00:42
  • 1
    @John Hascall this is not quite right – it is all about atomicity and not how many thread write. Even if two or more threads write to a volatile variable it doesn't need to be synchronized if they do not need the variable’s previous value to determine its new value – volatile make writing to a variable of any type atomic. Only reading and writing by multiple threads (like in a counter example) makes synchronization necessary. – Tomasz Stanczak Oct 27 '16 at 13:33
292

Difference Between Static and Volatile :

Static Variable: If two Threads(suppose t1 and t2) are accessing the same object and updating a variable which is declared as static then it means t1 and t2 can make their own local copy of the same object(including static variables) in their respective cache, so update made by t1 to the static variable in its local cache wont reflect in the static variable for t2 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 and t2) are accessing the same object and updating a variable which is declared as volatile then it means t1 and t2 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.

Marian Paździoch
  • 7,671
  • 9
  • 49
  • 88
Som
  • 4,300
  • 4
  • 25
  • 31
  • 7
    Hello @Som, Please correct me if I am wrong. But don't you think the statement "**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).**" should be "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)." – Jaikrat Jun 30 '15 at 19:35
  • @Jaikrat Yes that was very confusing for me. My understanding is that you're right and that this answer is wrong, as written. I would also like to be corrected if I'm wrong. – stuart Jul 07 '15 at 18:31
  • @Jaikrat Threads don't cache the static variables though but, do refer to the updated static variables . – Som Jul 08 '15 at 07:46
  • @Som Then would you like to correct the para and remove **but not in the context of Thread**. Thats very confusing. Thanks – Jaikrat Jul 09 '15 at 10:44
  • Sadly, this answer is incorrect. On modern CPUs, even a `volatile` variable can be shared among distinct CPU caches. This presents no problem because the cache negotiates exclusive ownership of the cache line prior to modify it. – David Schwartz Nov 11 '15 at 01:02
  • Hello @Som, Can Threads cache AtomicInteger variable as well like normal primitives ? – Peter Jul 12 '16 at 10:38
36

In addition to other answers, I would like to add one image for it(pic makes easy to understand)

enter image description here

static variables may be cached for individual threads. In multi-threaded environment if one thread modifies its 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

mrsrinivas
  • 27,898
  • 11
  • 107
  • 118
  • 1
    static variables are shared among objects under a thread? This should read static variables are shared among objects all objects regardless of threads. – cquezel Dec 11 '15 at 20:47
  • 1
    "volatile variables are shared among multiple threads(so objects as well)." Volatile does not change how variables are shared among multiple threads or objects. It changes how the runtime is allowed to cache the value. – cquezel Dec 11 '15 at 20:56
  • 1
    Your comment about static variables also applies to non static and the "will be cached" and "will not reflect" should probably be rephrased "may be cached" and "may not reflect". – cquezel Dec 13 '15 at 16:26
  • 5
    I was very confused. this picture cleared all my questions! – vins Mar 15 '16 at 00:32
5

I think static and volatile have no relation at all. I suggest you read java tutorial to understand Atomic Access, and why use atomic access, understand what is interleaved, you will find answer.

Community
  • 1
  • 1
Amitābha
  • 3,261
  • 4
  • 33
  • 55
4

In simple terms,

  1. 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 memory

  2. volatile: This keyword is applicable to both class and instance variables.

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

Have a look at this article by Javin Paul to understand volatile variables in a better way.

enter image description here

In absence of volatile keyword, the value of variable in each thread's stack may be different. By making the variable as volatile, all threads will get same value in their working memory and memory consistency errors have been avoided.

Here the term variable can be either static (class) variable or instance (object) variable.

Regarding your query :

Anyway a static variable value is also going to be one value for all threads, then why should we go for volatile?

If I need instance variable in my application, I can't use static variable. Even in case of static 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.

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 => memory consistency errors are still possible with volatile variables. To avoid side effects, you have to use synchronized variables. But there is a better solution in java.

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

Community
  • 1
  • 1
Ravindra babu
  • 42,401
  • 8
  • 208
  • 194
  • I really appreciate this answer. I knew what is the `volatile` earlier, but, this answer clarifies a lot for me why do I still need to use `volatile` with the `static` variable. – Arefe Nov 08 '18 at 03:12
  • volatile: This keyword is applicable to both class and instance variables. The statement you said above is incorrect regarding applicable to class. only two key words that applicable to variable is volatile and transient. so volatile wont applicable for class. – ASR Feb 22 '19 at 06:39
  • volatile is applicable to class ( static ) variables. Check out for Double locked singleton links in google and you can find that your understanding is wrong. https://stackoverflow.com/questions/18093735/double-checked-locking-in-singleton – Ravindra babu Feb 22 '19 at 11:08
  • private static volatile is valid declaration. – Ravindra babu Feb 22 '19 at 11:10
0

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.

Aslam anwer
  • 686
  • 9
  • 17
0

Not sure static variables are cached in thread local memory or NOT. But when I executed two threads(T1,T2) accessing same object(obj) and when update made by T1 thread to static variable it got reflected in T2.

-2

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.

  • 15
    *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.* => **right.** *So, the value of the variable in all the threads will be the same.* => **wrong, each thread will use the same value for the same Object, but each Object will have its own copy.** – stivlo Oct 30 '11 at 05:59