ダブル・チェック・ロッキング
2012年9月24日 (月) 09:14時点におけるimported>Administratorによる版 (→C# (Lazy))
ダブル・チェック・ロッキング(英語:Double Check Locking)とは、初回はロックなしで状態チェックを行い、そこで必要であれば再度ロックを掛けたのちに状態チェックを行うというソフトウェアの最適化技法、デザインパターンのひとつである。
ロックは非常にオーバーヘッドの大きい重い処理であるため、その発生回数を可能な限り減らすことで高速化を実現しようというものである。
ダブル・チェック・ロッキングは、主にマルチスレッド環境下でのシングルトンパターンを実装する際にオーバーヘッドの低減を目的として使われることが多い。
主なプログラミング言語での実装例
C#
C#における標準的なダブル・チェック・ロッキングの実装方法を示す。この記述方法ではC#のキーワードのひとつであるvolatileを用いているのがミソである。なおvolatileキーワードと同等の機能を提供していない.NET Framework系のプログラミング言語も多く、それらでは別の実装方法を検討する必要がある。
public class MySingleton
{
private static object _sync = new object();
private static volatile MySingleton _instance = null;
// プライベートコンストラクター
// ※本クラスを除き、newキーワードによるインスタンス生成を出来なくする。
private MySingleton()
{
}
//
public static MySingleton GetInstance()
{
// 1回目のチェック
// ロックしていないので高速に処理される
if (null == _instance)
{
// ロック
// ※このブロック内はクソ重い
lock (_sync)
{
// 2回目のチェック
if (null == _instance)
{
_instance = new MySingleton();
}
}
}
return _instance;
}
}
C# (Lazy)
.NET Framework 4.0では、標準でLazy<T>クラスが用意されており、それを使うことでよりシンプルにダブル・チェック・ロッキングを記述できるようになった[1]。 この記述方法はC#に依存した機能も特に使われておらず、.NET Framework系の様々なプログラミング言語へも特に悩むことなく移植・実装可能であると思われる。
using System;
public class MySingleton
{
private static readonly Lazy<MySingleton> _instance
= new Lazy<MySingleton>(() => new MySingleton());
private MySingleton()
{
}
public static MySingleton GetInstance()
{
return _instance.Value;
}
}
関連項目
参考文献
- ↑ Albahari, Joseph (2010). “Threading in C#: Using Threads”. C# 4.0 in a Nutshell. O'Reilly Media. ISBN 0596800959 . "
Lazy<T>
actually implements […] double-checked locking. Double-checked locking performs an additional volatile read to avoid the cost of obtaining a lock if the object is already initialized."