0

SOや他の場所で何百万もの投稿を読んだことで、このトピックがどんどん増えていることは知っていますが、明確な答えはまだ見つかりません。このように見える冗長性に腹を立てている場合は、お詫び申し上げます。

ライトワンス、リードミリオンのリソースがある状況があります。リソースの作成には非常に費用がかかり、書き込みロックの競合も非常に高くなる可能性があります。さらに、これがどのプロセッサで実行されるかを予測できないため、その下にあるメモリモデルがわかりません。.NET 3.5、.NET 4.0、およびMono2.10に組み込まれているアセンブリの3つのバージョンをコンパイルしています。

リソースの競合が高いため、これを可能な限り効率的にする必要があり、少なくとも読み取りにはロックフリーパターンを使用したいと思います。リソースを作成するためのダブルロックチェックパターンは理解していますが、メモリバリアの外側にある_resourceにアクセスするため、(すべてのプロセッサで)機能するかどうかについて意見の相違があります。_resourceフィールドでvolatileを使用する必要がありますか?ReaderWriterLockSlimは、このシナリオにより適していますか?他にどのような質問をする必要がありますか?

if(_resource == null)
{
    lock(_locker)
    {
        if(_resource == null)
        {
            //create resource here...
        }      
    }
}

さらに、これらの数があります:

if(_resource == null)
{
    return _resourceDefault;
}

return _resource.GetSomething();
4

1 に答える 1

1

私のコメントを回答に昇格させることにしました。

シングルトンの読み取りの作成については、http://msdn.microsoft.com/en-us/library/ff650316.aspxを参照してください。それは、ダブルチェックロックに関連する問題のいくつかを説明する詳細な論文をクロスリンクします。完全に安全にするために、マイクロソフトの記事では揮発性を推奨しています。

リーダーライターロックは、シングルトンを作成することだけが本当に必要な場合は、実際には何も購入しません(1回限り...ロックプロモーションなどは必要ありません。リソースの作成を保護する必要があります)。リソースが作成されると、ロックに触れることはまったくありません。

私はあなたのシングルトンへのアクセスを常に静的なプロパティ/メソッドを通過するように設計しているので、あなたは常にダブルチェックを行うことができます。

リソースのデフォルトについては、あなたの状況について適切に答えるのに十分な知識がないと思います。プライマリリソースが(作成される前を除いて)nullになると予想しますか?ユースケースによっては、Moniter.TryEnterを使用できる場合があります。これは非ブロックであり、ロックを受け取ったかどうかを通知する値を返します。シングルトンを作成するためのロックをすぐに取得できなかった場合は、デフォルトに戻すことができます。

于 2012-07-16T18:12:37.887 に答える