Is it thread safe that java anonymous inner-class implements Runnable and shared outer-class object?

279 Views Asked by At
public class Main {

    public static void main(String[] args) {
        Status status = new Status();
        new Thread(new Runnable() {
            @Override
            public void run() {
                status.setStatus(true);
            }
        }).start();
    }
}

class Status {
    boolean status = false;
    public void setStatus(boolean status) {
        this.status = status;
    }
    public boolean getStatus() {return status;}
}

As code shown, created-thread shared main-thread status object.I think it is not thread safe, due to cpu cache,main-thread and created-thread load status object to their own cache, when created-thread call 'setStatus' method it only update its cache data and main-thread can not see updated data right now. So it needs synchronization. Do I understand correctly?

1

There are 1 best solutions below

2
On

See jls 17.4.5 for the happens-before rules.

A call to start happens-before any actions in the started thread. So the new thread will see the status object as created on the main thread.

But the change to status isn't guaranteed to be visible to the main thread. If the main thread joins to the new thread then a happens-before rule will be applicable and the change would be visible once the new thread finished. If you want the change to be seen without requiring the new thread to finish you could make the Boolean volatile or change its type to AtomicBoolean. Or put the synchronized keyword on both the setter and getter.

Be aware the JVM isn't required to not make this visible, it just isn't required to. Ymmv depending on the jvm implementation.

So I think your understanding is correct.