差分
ナビゲーションに移動
検索に移動
ページの作成:「'''ダブル・チェック・ロッキング'''(英語:Double Check Locking)とは、初回はロックなしで状態チェックを行い、そこで必要...」
'''ダブル・チェック・ロッキング'''(英語:Double Check Locking)とは、初回は[[ロック]]なしで状態チェックを行い、そこで必要であれば再度[[ロック]]を掛けたのちに状態チェックを行うという[[ソフトウェア]]の[[最適化]]技法、[[デザインパターン]]のひとつである。
[[ロック]]は非常に[[オーバーヘッド]]の大きい重い処理であるため、その発生回数を可能な限り減らすことで高速化を実現しようというものである。
ダブル・チェック・ロッキングは、主に[[マルチスレッド]]環境下での[[シングルトンパターン]]を実装する際に[[オーバーヘッド]]の低減を目的として使われることが多い。
== 主なプログラミング言語での実装例 ==
=== C# ===
[[C Sharp|C#]]における標準的なダブル・チェック・ロッキングの実装方法を示す。この記述方法では[[C Sharp|C#]]のキーワードのひとつであるvolatileを用いているのがミソである。なおvolatileキーワードと同等の機能を提供していない[[.NET Framework]]系の[[プログラミング言語]]も多く、それらでは別の実装方法を検討する必要がある。
<source lang="csharp">
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;
}
}
</source>
=== C# (Lazy) ===
[[.NET Framework 4.0]]では、標準でLazy<T>クラスが用意されており、それを使うことでよりシンプルにダブル・チェック・ロッキングを記述できるようになった<ref>{{cite book
|title=C# 4.0 in a Nutshell
|last=Albahari
|first=Joseph
|isbn=0596800959
|year=2010
|publisher=O'Reilly Media
|chapter=Threading in C#: Using Threads
|chapterurl=http://www.albahari.com/threading/part3.aspx#_LazyT
|quote=<code>Lazy<T></code> 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.
}}</ref>。
この記述方法は[[C Sharp|C#]]に依存した機能も特に使われておらず、[[.NET Framework]]系の様々な[[プログラミング言語]]へも特に悩むことなく移植・実装可能であると思われる。
<source lang="csharp">
public class MySingleton
{
private static readonly Lazy<MySingleton> _instance =
new Lazy<MySingleton>(() => new MySingleton());
private MySingleton()
{
}
public static MySingleton GetInstance()
{
return _instance.Value;
}
}
</source>
== 関連項目 ==
* [[マルチスレッド]]
* [[並列処理]]
* [[デザインパターン]]
== 参考文献 ==
{{reflist}}
== 外部リンク ==
{{stub}}
[[ロック]]は非常に[[オーバーヘッド]]の大きい重い処理であるため、その発生回数を可能な限り減らすことで高速化を実現しようというものである。
ダブル・チェック・ロッキングは、主に[[マルチスレッド]]環境下での[[シングルトンパターン]]を実装する際に[[オーバーヘッド]]の低減を目的として使われることが多い。
== 主なプログラミング言語での実装例 ==
=== C# ===
[[C Sharp|C#]]における標準的なダブル・チェック・ロッキングの実装方法を示す。この記述方法では[[C Sharp|C#]]のキーワードのひとつであるvolatileを用いているのがミソである。なおvolatileキーワードと同等の機能を提供していない[[.NET Framework]]系の[[プログラミング言語]]も多く、それらでは別の実装方法を検討する必要がある。
<source lang="csharp">
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;
}
}
</source>
=== C# (Lazy) ===
[[.NET Framework 4.0]]では、標準でLazy<T>クラスが用意されており、それを使うことでよりシンプルにダブル・チェック・ロッキングを記述できるようになった<ref>{{cite book
|title=C# 4.0 in a Nutshell
|last=Albahari
|first=Joseph
|isbn=0596800959
|year=2010
|publisher=O'Reilly Media
|chapter=Threading in C#: Using Threads
|chapterurl=http://www.albahari.com/threading/part3.aspx#_LazyT
|quote=<code>Lazy<T></code> 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.
}}</ref>。
この記述方法は[[C Sharp|C#]]に依存した機能も特に使われておらず、[[.NET Framework]]系の様々な[[プログラミング言語]]へも特に悩むことなく移植・実装可能であると思われる。
<source lang="csharp">
public class MySingleton
{
private static readonly Lazy<MySingleton> _instance =
new Lazy<MySingleton>(() => new MySingleton());
private MySingleton()
{
}
public static MySingleton GetInstance()
{
return _instance.Value;
}
}
</source>
== 関連項目 ==
* [[マルチスレッド]]
* [[並列処理]]
* [[デザインパターン]]
== 参考文献 ==
{{reflist}}
== 外部リンク ==
{{stub}}