javamultithreadinghappens-before

Will JVM update value of field for all threads with usage of Happens-Before, without assignment value to field directly?


I already know that if I write to non volatile field from another thread, he could probably cache it so all other threads won't see actual value. But if I would invoke for example start() on thread object AFTER assignment value to filed, JVM will update this value for all other threads. But will JVM update value of this field if I will do same action but will assign value to field not directly, like this: object.field = 100 but with invoking method object.setFiled(100).

public class Main {
int value;

public static void main(String[] args) {
    Main main = new Main();
    main.value = 100;
    new Thread(() -> System.out.println(main.getValue())).start();
    

In this case value of field will be same for all other threads for sure

}

public int getValue() {
    return value;
}
}

public class Main {
private int value;

public static void main(String[] args) {
    Main main = new Main();
    main.setValue(100);
    new Thread(() -> System.out.println(main.getValue())).start();

But will be result same in this case?

}

public int getValue() {
    return value;
}

public void setValue(int value) {
    this.value = value;
}
}

Solution

  • The mechanics of how something gets updated in a thread, whether it be direct field access or through setters doesn't matter in this case. JLS 17.4.5 states that "A call to start() on a thread happens-before any actions in the started thread." And within a single thread "If x and y are actions of the same thread and x comes before y in program order, then [x happens before y]". In this case a method setter or field assignment that would make a value visible to the original thread also makes that value visible to the newly started thread. Roughly, anything that was visible to the thread calling start() at the time start() was called will be similarly visible to the new thread as long as the object being viewed isn't mutated and the attempts to view state don't mutate things (eg. LinkedHashMap#get with accessOrder=true).