Search code examples
javastaticinitializationnon-thread-safe

Initializing a static Java constant from a non-thread-safe method


Let there be a class definition like

  public static class Bootstrapper {

    public static final Object DEFAULT_VALUE = getDefaultValue();

    private static Object getDefaultValue() {
      if (DEFAULT_VALUE == null) {
        return createValue(); // Not thread safe
      }
      return DEFAULT_VALUE;
    }
  }

where the createValue() method does not reference the DEFAULT_VALUE field, is only otherwise called in the constructor of the Bootstrapper class and is not thread safe.

Is there any issue (aside from programming style) with the above code? Presumably thread safety is not a problem, given the rules for class initialization, but anything important for the programmer to be aware of?


Solution

  • This is safe from a threading point of view, as the class loading is thread safe and that value will be set (so getDefaultValue()) will be called after the class is loaded, but before it leaves the class loading code.

    To answer PNS comment on the original question above, if the class is loaded by 2 different classloaders you are in trouble anyway, as using the synchronized keyword on getDefaultValue() will create a lock on the class... and since you have 2 classes, each one will be fully independent. You can read this in the Java Language Specification, section 4.3.4 When Reference Types Are the Same (for JLS 8).