Per the JMM, section 9.2.3
The rules for class initialization ensure that any thread that reads a static field will be synchronized with the static initialization of that class.
I am trying to understand what happens when a class (b) attempts to read a static field from class (a), and (a) is still being initialized. Is there any guarantee that (b) will read the correct value of (a) (i.e. after static initialization)?
As an example, is there a data race on field_long?
class TextField {
public static final FieldType TEXT_FIELD_TYPE = new FieldType();
static {
TEXT_FIELD_TYPE.set_field_long(1L);
};
}
class FieldType {
public Long field_long;
public void set_field_long(Long l) { field_long = l; }
public Long get_field_long() { return field_long; }
public FieldType(){ set_field_long(-1L); }
public FieldType(FieldType ref) { this.field_long = ref.get_field_long(); }
}
public class Main {
public static void main(String... args) {
Thread t1 = new Thread(() -> {
FieldType f = new FieldType(TextField.TEXT_FIELD_TYPE);
});
Thread t2 = new Thread(() -> {
FieldType f = new FieldType(TextField.TEXT_FIELD_TYPE);
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyClass.afieldon a class that isn't loaded yet, the class loading happens first, then all initialization, then your code continues executing with the class now loaded in the system.Mainis loaded, thenmainbegins executing, thenThreadgets loaded, then (likely) the parameterTextFieldis evaluated and that class is loaded, thenFieldTypeclass is loaded, and only then does the code continue tot1.start().