Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it guaranteed that volatile field would be properly initialized

Here:

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.

Are the same guarantees held for the volatile field? What if the y field in the following example would be volatile could we observe 0?

class FinalFieldExample { 
final int x;
int y; 
static FinalFieldExample f;

public FinalFieldExample() {
    x = 3; 
    y = 4; 
} 

static void writer() {
    f = new FinalFieldExample();
} 

static void reader() {
    if (f != null) {
        int i = f.x;  // guaranteed to see 3  
        int j = f.y;  // could see 0
    } 
} 

}

like image 231
Hlib Avatar asked Oct 19 '21 22:10

Hlib


1 Answers

Yes, it is possible to see 0 when

class FinalFieldExample { 
  final int x;
  volatile int y;
  static FinalFieldExample f;
  ...
}

The short explanation:

  • writer() thread publishes f = new FinalFieldExample() object via a data race
  • because of this data race, reader() thread is allowed see f = new FinalFieldExample() object as semi-initialized.
    In particular, reader() thread can see a value of y that was before y = 4; — i.e. initial value 0.

More detailed explanations are here.

You can reproduce this behavior on ARM64 with this jcstress test.

like image 115
user17206833 Avatar answered Oct 25 '22 06:10

user17206833