I used this pattern in a few projects, (this snipped of code is from CodeCampServer), I understand what it does, but I’m really interesting in an explanation about this pattern. Specifically:
- Why is the double check of
_dependenciesRegistered. - Why to use
lock (Lock){}.
Thanks.
public class DependencyRegistrarModule : IHttpModule
{
private static bool _dependenciesRegistered;
private static readonly object Lock = new object();
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
public void Dispose() { }
private static void context_BeginRequest(object sender, EventArgs e)
{
EnsureDependenciesRegistered();
}
private static void EnsureDependenciesRegistered()
{
if (!_dependenciesRegistered)
{
lock (Lock)
{
if (!_dependenciesRegistered)
{
new DependencyRegistrar().ConfigureOnStartup();
_dependenciesRegistered = true;
}
}
}
}
}
This is the Double-checked locking pattern.
The
lockstatement ensures that the code inside the block will not run on two threads simultaneously.Since a
lockstatement is somewhat expensive, the code checks whether it’s already been initialized before entering the lock.However, because a different thread might have initialized it just after the outer check, it needs to check again inside the lock.
Note that this is not the best way to do it.