Home > Mobile >  Can another thread see an effectively immutable object in an inconsistent state if it is published w
Can another thread see an effectively immutable object in an inconsistent state if it is published w

Time:02-22

According to Java Concurrency in Action if we have the following class:

public class Wrapper {
  private int num;

  public Wrapper(int num) {
    this.num = num;
  }

  public void assertCorrectness() {
    if (num != num)
      throw new AssertionError("This is false");
  }
}

and we initialise an instance of this class and publish it in a non-safe way (through a simple public field for example), then the assertCorrectness() might indeed throw an AssertionError, if called from another thread. In other words, this means that some another thread might see an up-to-date reference to the instance, but the state of the instance itself could be out-of-date (so a thread can see an object exists but it is in a partially constructed / inconsistent state).

On the other hand, it is said that publishing an instance of this class through a volatile reference is considered safe. However it was my understanding that volatile just guarantees that any thread will always see an up-to-date version of a reference, but not the object's state being referenced. So we can be sure that if one thread assigns a new instance of the Wrapper class to a volatile field, then all the other threads will see that the reference was updated. But is there a risk that they will still see an object in an inconsistent / partially constructed state?

CodePudding user response:

No, because volatile being used establishes a happens-before relationship. Without it various reorderings and other things are allowed, which make the inconsistent state possible, but with it the JVM must give you the expected outcome.

In this case volatile is not used for the visibility effects (threads seeing up to date values), but the safe publishing provided by the happpens-before. This feature of volatile is often left out when its use is explained.

CodePudding user response:

The answer above is correct.

Just keep in mind that effectively immutable safe publication behaves unintuitively in some cases.
For instance:

  1. If

    • at first thread 1 safely publishes object o to thread 2
    • then thread 2 unsafely publishes object o to thread 3

    in the end thread 3 can see object o in an inconsistent state
    See [1] and [2]

  2. also this

Real immutable objects have no such problems.

  • Related