Gaurav Singh
Gaurav Singh

Reputation: 47

Safe Publication of Java object after calling setter on the object

Will calling a setter after constructor execution but before returning the reference will be a safe publication ?

public class SafePublication {
    private int i = 0;
    private SafePublication() {
            i = 10;
    }

    // Here we are calling setter are object creation. 
    //Will this change be visible to other threads
   public static SafePublication getInstance() {
           SafePublication pub = new SafePublication();
           pub.setVal(20);
           return pub;
   }

   private void setVal(int x) {
           this.i = x;
   }
}

Upvotes: 1

Views: 159

Answers (1)

Stephen C
Stephen C

Reputation: 718836

No it won't be safe.

The setVal method is not synchronized, and i is not volatile. Therefore, there will be no synchronization point between an update to i (via setVal) and any code run on another thread that reads i. The fact that the setVal call happens in the thread that constructs the instance makes on difference.

The bottom line is that another thread may see the value of i as any one of 0, 10 or 20.


How may another thread see that value if the reference to the object has not been returned yet?

It is not. The problem is that the other thread may not see the correct value of i.

I think you are confusing this situation with the case where the field is final. There, the JLS does specify that the field is safely published. The problem is that this guarantee does not apply to non-final fields; see JLS 17.5. The wording is as follows:

"An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields. "

(Emphasis added)


i would rather say another thread may see the value of i as any one of 10 or 20. It is guaranteed not to see 0.

AFAIK, there is nothing in JLS 17.4 or JLS 17.5 that offers that guarantee. The only thing that is guaranteed is that nothing will see the value of i before default initialization has taken place. (Please feel free to prove me wrong ... with references to the JLS.)

Upvotes: 3

Related Questions