2

SyncHashtablein defined in .Net フレームワーク BCLの実装を行いました。

このクラスは、複数のリーダーとライターへの同期アクセスを提供します。

メソッドの1つは次のように実装されています

public override Object this[Object key] {
            get {
                    return _table[key];
            }
            set {
                lock(_table.SyncRoot) {
                    _table[key] = value;
                }
            }
        }

私の意見では、オブジェクトにアクセスする前に get メソッドも Syncroot をロックする必要があります。

シナリオを考えてみましょう:

スレッド 1: からキーを削除していHashtableます。

スレッド 2 : キーを使用してオブジェクトを読み取る。

オブジェクトの読み取り中にスレッド 2 でコンテキスト スイッチが発生し、スレッド 1 がオブジェクトを削除すると、読み取り操作が失敗するか、一貫性のない結果が得られます。

したがって、このメソッドをこのように実装することはできませんでした

public override Object this[Object key] {
            get {
                 lock(_table.SyncRoot) 
                  {   
                   return _table[key];
                  }
            }
            set {
                lock(_table.SyncRoot) {
                    _table[key] = value;
                }
            }
        }

ありがとう

4

2 に答える 2

2

Hashtableこれらの状況ではすでにスレッドセーフであるため、読み取りのためにロックする必要はありません。

状態のドキュメントHashtable:

Hashtable は、複数のリーダー スレッドと 1 つの書き込みスレッドで使用できるスレッド セーフです。

書き込みアクセスをロックすることにより、実質的に 1 つのライターしか存在しないため、読み取りをロックする必要がなくなります。

これは には当てはまりますがHashtable、 には当てはまらないことに注意してくださいDictionary<TKey, TValue>

于 2011-06-05T07:52:02.397 に答える
0

Hashtablelock キーワードは暗黙的なリーダー/ライター ロックではなくモニターであるため、正しいと思います。これは間違いなく望ましくない影響を引き起こす可能性があります。ただし、今日の状況を考えると、.NET 3.5 のReactive Extensionsに目を向けると、.NET 4.0 の一部として新しい並行クラスを含む System.Threading アセンブリが同梱されています。これらのクラスは、コレクションへのマルチスレッド アクセスを処理するのに適しています。

于 2011-06-05T07:51:14.190 に答える