Question

I guess this has to do with a happens-before rule, but I have no concrete explanation ... My question is, if the nonFinalField reference to "Hello World" is guaranteed to be seen by Thread "thread"? And no I don't want to make nonFinalField final and it will not be updated later as there is also no method allowing it.

Hope we can demystify this example with a reasonable explanation.

Thank you in advance.

Kind regards, Hermann

public class Test2 {

    private String nonFinalField;

    public Test2() {

        nonFinalField="Hello World";
    }

    void startThread() {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("nonFinalField: " + nonFinalField);
            }
        });
        thread.start();
    }

    public static void main(String[] args) {
        Test2 test = new Test2();
        test.startThread();
    }
}
Was it helpful?

Solution

Yes, the Thread started in startThread is guaranteed to see the value of nonFinalField because starting a thread establishes a "happens before" relationship between the parent (the thread calling main) and child thread (the thread started in startThread).

This is listed in the lanuage spec in 17.4.4 (third bullet).

OTHER TIPS

As there is no way you can call startThread before the object is constructed (and therefore completely initialises) then this thread will certainly see the non-final field initialised.

However, if another thread manages to look at it before the thread is run it is possible for the other thread to see an uninitialised field.

Remember that it is possible to look at private fields through reflection.

From my understanding, it will be visible. Using the 'happens-before' relationship rules in the java.util.concurrent package javadoc:

  • Each action in a thread happens-before every action in that thread that comes later in the program's order.
  • A call to start on a thread happens-before any action in the started thread.

Since happens-before is transitive, this implies that 'Each action in ThreadA prior to calling ThreadB.start() happens-before every action in ThreadB'.

So if ThreadA is your main thread, and ThreadB is the one you're explicitly creating, then events in the main thread before starting the second thread will be visible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top