Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What exactly does the final keyword guarantee regarding concurrency?

I think I've read that the final keyword on a field guarantees that if thread 1 instantiates the object containing the field, then thread 2 will always see the initialized value of that field if thread 2 has a reference to the object (provided it was properly constructed). It also says in the JLS that

[Thread 2] will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are. (section 17.5 of JLS)

That implies that if I have class A

class A {   private final B b = new B();   private int aNotFinal = 2;   ... 

and class B

class B {   private final int bFinal = 1;   private int bNotFinal = 2;   ... 

then aNotFinal is not guaranteed to be initialized by the time thread 2 gets a reference to class A, but field bNotFinal is, because B is an object referenced by a final field, as specified in the JLS.

Do I have this right?

Edit:

A scenario where this could happen would be if we have two threads concurrently executing getA() on the same instance of a class C

class C {   private A a;    public A getA(){     if (a == null){       // Thread 1 comes in here because a is null. Thread B doesn't come in        // here because by the time it gets here, object c        // has a reference to a.       a = new A();     }     return a; // Thread 2 returns an instance of a that is not fully                                    // initialized because (if I understand this right) JLS                // does not guarantee that non-final fields are fully                // initialized before references get assigned   } } 
like image 825
user384842 Avatar asked Dec 02 '14 16:12

user384842


People also ask

What is the purpose of the keyword final?

The final keyword is a non-access modifier used for classes, attributes and methods, which makes them non-changeable (impossible to inherit or override). The final keyword is useful when you want a variable to always store the same value, like PI (3.14159...). The final keyword is called a "modifier".

What is are true about the final keyword?

If a variable is declared with the final keyword, its value cannot be changed once initialized.

Are final objects thread safe?

Final Variables are also thread-safe in java because once assigned some reference of an object It cannot point to reference of another object.

What is the best situations when we use final keyword?

In Java, the final keyword is used to denote constants. It can be used with variables, methods, and classes. Once any entity (variable, method or class) is declared final , it can be assigned only once.


1 Answers

What you are saying is true.

Marking a field as final forces the compiler to complete initialization of the field before the constructor completes. There is no such guarantee however for non-final fields. This might seem weird, however there are many things done by the compiler and JVM for optimization purposes such as reordering instructions, that cause such stuff to occur.

The final keyword has many more benefits. From the Java Concurecncy in Practice:

Final fields can't be modified (although the objects they refer to can be modified if they are mutable), but they also have special semantics under the Java Memory Model. It is the use of final fields that makes possible the guarantee of initialization safety (see Section 3.5.2) that lets immutable objects be freely accessed and shared without synchronization.

The Books says then:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed object; or
  • Storing a reference to it into a field that is properly guarded by a lock.
like image 58
javaHunter Avatar answered Oct 02 '22 05:10

javaHunter