Code Inspection: Possible incorrect implementation of Double-Check Locking pattern. Read access to checked field
Consider the following piece of code:
public class Foo
{
private static volatile Foo instance;
private static readonly object padlock = new object();
public static Foo GetValue()
{
if (instance == null)
{
lock (padlock)
{
if (instance == null)
{
instance = new Foo();
instance.Init();
}
}
}
return instance;
}
private void Init()
{
...
}
};
If we assume that Init()
is a method used to initialize the state of Foo
, then the above code may not function as expected due to the memory model not guaranteeing the order of reads and writes. As a result, the call to Init()
may actually occur before the variable instance is in a consistent state.
There are two ways to resolve this issue for the code above.
The first, and most obvious, is to simply relocate the contents of Init()
to a private constructor.
The second is to perform the initialization in a non-checked variable and then assigned it to the checked one, thus eliminating the ordering problem. Thus, the code in the inner if statement from the above example could be re-written as:
var temp = new Foo();
temp.Init();
instance = temp;