2

Please consider following code snippet.

public class Visibility {

    private volatile SomeData data;

    public static class SomeData {

        private int number;

        public SomeData(int number) {
            this.number = number;
        }

        public int getNumber() {
            return number;
        }
    }

    public void initialize() {
        data = new SomeData(42);
    }

    public SomeData getData() {
        return data;
    }
}

If number field was final, any thread that sees data reference is not null (after other thread called initialize) is also guaranteed to see number field value as 42.

Do we have the same guarantees for non final field? In other words, is it possible for some thread to observe non-null data reference, but number field as 0?

Thanks in advance!

alxg2112
  • 318
  • 2
  • 11

2 Answers2

2

It is not possible for some thread to observe non-null data reference, but number field as 0.

See the doc of volatile:

This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.

So when you get a non-null data, it must have been successfully initiated, the number must be non-zero.

xingbin
  • 27,410
  • 9
  • 53
  • 103
1

In general, yes, it is possible to see a field in a partially constructed state if the field is not published in a safe manner. In the particular case of your question, the volatile keyword is a satisfactory form of safe publication. According to Java Concurrency in Practice:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer.
  • Storing a reference to it into a volatile field.
  • Storing a reference to it into a final field.
  • Storing a reference to it into a field that is properly guarded by a (synchronized) lock.

For more information, see the following:

Justin Albano
  • 3,809
  • 2
  • 24
  • 51