Double-checked locking can be used for lazy initialization of ``++volatile++`` fields, but only if field assignment is the last step in the ``++synchronized++`` block. Otherwise you run the risk of threads accessing a half-initialized object. == Noncompliant Code Example ---- public class MyClass { private volatile List strings; public List getStrings() { if (strings == null) { // check#1 synchronized(MyClass.class) { if (strings == null) { strings = new ArrayList<>(); // Noncompliant strings.add("Hello"); //When threadA gets here, threadB can skip the synchronized block because check#1 is false strings.add("World"); } } } return strings; } } ---- == Compliant Solution ---- public class MyClass { private volatile List strings; public List getStrings() { if (strings == null) { // check#1 synchronized(MyClass.class) { if (strings == null) { List tmpList = new ArrayList<>(); tmpList.add("Hello"); tmpList.add("World"); strings = tmpList; } } } return strings; } } ---- == See * https://wiki.sei.cmu.edu/confluence/x/6zdGBQ[CERT, LCK10-J.] - Use a correct form of the double-checked locking idiom === See Also * S2168 - Double-checked locking should not be used ifdef::env-github,rspecator-view[] == Comments And Links (visible only on this page) include::comments-and-links.adoc[] endif::env-github,rspecator-view[]