元のDouble-Checked Lockingパターンの問題は十分に文書化されています: C++ and the Perils of Double-Checked Locking。SOに関する質問でこのトピックがかなり頻繁に出てくるのを見てきました。
元のパターンの競合状態の問題を解決しているように見えるバージョンを思いつきましたが、問題ないように見えますか?
以下のコードでは、LOCK が適切に実装されたミューテックス型であり、ロック/ロック解除時にメモリ バリアを引き起こすと想定しています。また、パターンの一部ではないため、インスタンスの割り当て解除を処理しようとはしません。
シングルトンを実行する他の可能な方法を認識していますが、それは私が求めているものではありません。私は具体的にパターンについて質問しています - ミューテックスロックの外側に割り当てを行うことで競合状態は解決されますか?.
template <typename T, typename LOCK>
class Singleton
{
private:
static T * instance_;
static LOCK mutex;
// private - inaccessible
Singleton();
Singleton(const Singleton &);
Singleton & operator=(const Singleton &);
public:
static T * get_instance()
{
if (instance_ == NULL)
{
T * temp = new T;
mutex.lock();
if (instance_ == NULL)
instance = temp;
else
delete temp;
mutex.unlock();
}
return instance_;
}
};