[concurrency-interest] Reordering and Immutability

Yann Le Tallec ylt at letallec.org
Sun Feb 3 13:37:03 EST 2013


I have a couple of questions regarding the following class:

public class SomeClass {
  private static Resource resource = null; //w0

  public static Resource getInstance() {
    if (resource == null)                  //r1
      resource = new Resource();           //w1
    return resource;                       //r2

(1) Can getInstance() return null?

Example of an execution that returns null, with three threads T0, T1 and T2:
- T0 initialises resource to null (write w0)
- T1 reads null at r1 and assigns a new Resource instance to resource (write w1)
- T1 returns a non null value
- T2 reads w1 at r1 in the if condition and does not execute the if body
- T2 reads w0 at r2 and returns null

The execution seems happens-before consistent as both w0 and w1 are
observable by r1 and r2 (but I'm not sure if it is valid with regards
to the causality requirements of the JMM).
This possible reordering is one of the reasons why String#hashcode
uses a local variable I believe.

(2) Same question with resource declared as "private static Resource
resource;" (without the "= null") and with the additional assumption
that Resource is immutable

- I am told that "Resource resource; can't race whereas Resource
resource = null; can", but I don't see why they are different from a
JMM perspective.
- The resource variable being non-final, I don't think immutability
makes a difference here as null is still a valid and observable value.


ps: JCiP has an UnsafeLazyInitialization example similar to SomeClass
(without the "=null") and states in 16.3 that it would be safe if
Resource were immutable, so I guess I'm missing something and that
null is not a possible outcome.

More information about the Concurrency-interest mailing list