Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Final fields cannot be Volatile in Java? [duplicate]

Tags:

java

volatile

I would like to understand why a Reference that is declared as final cannot be declared as Volatile. There is a similar question on SO [Why can an Object member variable not be both final and volatile in Java?

[1]: Why can an Object member variable not be both final and volatile in Java? but I am not sure if the FINAL is understood in that answer.

Now The state of a final variable can definitely be changed after it has been initialized. Only the reference cannot be initialized to another object.

For eg consider the below member variable

final StringBuilder sb = new StringBuilder("CAT");

Now another thread changes sb as :

sb.append("S");

Will this change be available to different threads as per Java memory model if this variable is Non-Volatile ?

EDIT : I changed StringBuffer to StringBuilder for some people to make my point clear.

like image 335
Geek Avatar asked Sep 11 '13 18:09

Geek


2 Answers

volatile implies the field will change. If it is final you will never change it and such doesn't make sense.

Will this change be available to different threads as per Java memory model if this variable is Non-Volatile ?

Declaring a field volatile has no effects on its content or modifications after the volatile write occurs. If the field is volatile or non-volatile the memory effects of append are dictated by the implementation of StringBuffer.

So in the case of StringBuffer it does ensure memory visibility but not for the reason you think. StringBuffer is syncrhonized (thread-safe) so you will have an always up to date value of the content.

StringBuilder on the other hand is not synchronized and memory visibility is not guaranteed. So if you tried to swap the two out for a multihreaded test, you would see different results.

like image 113
John Vint Avatar answered Oct 16 '22 00:10

John Vint


Because volatile affects the behavior of how Threads access and edit the variable. In your code example, the variable is a reference (sb) to an object. So this means volatile has no effect on the object. final locks the reference. So if you append text, you are not changing the reference. Thus, it makes no sense to use volatile and final at the same time.

Will this change be available to different threads as per Java memory model if this variable is Non-Volatile ?

Because you are using a non thread safe implementation by using StringBuilder, there is no guarantee that all Threads are having the latest state of the StringBuilder.

like image 20
Martijn Courteaux Avatar answered Oct 15 '22 22:10

Martijn Courteaux