シングルトンは、特定の種類のオブジェクトが、プログラム全体で 1 つしか存在しないようにします。二重検査されたロックは、マルチスレッドアプリケーションでシングルトンを初期化する一般的で効率的な方法です。次のコードは、この実装方法を示します。
100 class Singleton { 101 public: 102 static Singleton* instance(); 103 ... 104 private: 105 static Singleton* ptr_instance; 106 }; 107 108 Singleton* Singleton::ptr_instance = 0; ... 200 Singleton* Singleton::instance() { 201 Singleton *tmp; 202 if (ptr_instance == 0) { 203 Lock(); 204 if (ptr_instance == 0) { 205 tmp = new Singleton; 206 207 /* Make sure that all writes used to construct new 208 Singleton have been completed. */ 209 memory_barrier(); 210 211 /* Update ptr_instance to point to new Singleton. */ 212 ptr_instance = tmp; 213 214 } 215 Unlock(); 216 } 217 return ptr_instance;
行 202 の ptr_instance の読み取りは、ロックによって意図的に保護されていません。このため、マルチスレッド環境で Singleton がすでにインスタンス化されているかどうかを判別するチェックが効率的になります。変数 ptr_instance の行 202 での読み取りと行 212 での書き込みとの間でデータの競合があるが、プログラムは正しく動作することに注意してください。ただし、データの競合を許可する正しいプログラムを作成すると、余分な注意が必要になります。たとえば、上記の二重検査されたロックのコードで、行 209 での memory_barrier() の呼び出しは、Singleton を構築するためのすべての書き込みが完了するまで、ptr_instance がスレッドによって非 NULL として認識されないようにするために使用されます。