Multithreaded Singleton: Double-check locking
The following code ensures,
Only one thread can enter the critical area (lock statement)
Only one instance is created and only when the instance is
needed (get accessor)
The variable is declared to be volatile to ensure that
assignment to the instance variable completes before the instance variable can
be accessed. The volatile modifier is usually used for a field that is accessed
by multiple threads without using the lock statement to serialize access. Using
the volatile modifier ensures that one thread retrieves the most up-to-date
value written by another thread.
This uses a syncRoot instance to lock on, rather than
locking on the type itself, to avoid deadlocks.
Double-check locking solves the thread concurrency problems
while avoiding an exclusive lock in every call to the Instance property method.
The first check avoids an exclusive lock in every call to
the Instance property method.
The second check ensures that instance is created only once.
Without the second check, check the following scenario.
Thread 1 locks synRoot
Thread 1 started initializing singleton object.
Thread 2 enters and waits at lock syncroot
Thread 1 finishes the initialization of singleton object and
exits.
Thread 2 enters and starts another initialization!
using System;
public sealed class Singleton
{
private static
volatile Singleton instance;
private static
object syncRoot = new Object();
private
Singleton() { }
public static
Singleton Instance
{
get
{
// First
check
if
(instance == null)
{
lock
(syncRoot)
{
//
Second check
if
(instance == null)
instance = new Singleton();
}
}
return
instance;
}
}
}
No comments:
Post a Comment