6

私はカーゴカルトプログラミングの習慣を身につけたと思います:

Dictionary または List を持つクラス (完全にカプセル化されている: 直接アクセスされることはなく、クラスのメンバー メソッドによってのみ変更される) など、クラスをスレッドセーフにする必要があるときはいつでも、次のように 2 つのオブジェクトを作成します。

public static class Recorder {

    private static readonly Object _devicesLock = new Object();
    private static readonly Dictionary<String,DeviceRecordings> _devices;

    static Recorder() {

        _devices = new Dictionary<String,DeviceRecordings>();

        WaveInCapabilities[] devices = AudioManager.GetInDevices();
        foreach(WaveInCapabilities device in devices) {

            _devices.Add( device.ProductName, new DeviceRecordings( device.ProductName ) );
        }
    }//cctor

    // For now, only support a single device.

    public static DeviceRecordings GetRecordings(String deviceName) {

        lock( _devicesLock ) {

            if( !_devices.ContainsKey( deviceName ) ) {

                return null;
            }

            return _devices[ deviceName ];
        }
    }//GetRecordings
}//class

この場合、すべての操作をブロック_devices内にラップします。lock( _devicesLock ) {これが必要かどうか疑問に思い始めています。辞書を直接ロックしないのはなぜですか?

4

2 に答える 2

10

あなたのユースケースでは、ディクショナリはプライベートであるため、ディクショナリをロックしても問題ありません。デッドロックを防ぐために、クラスを慎重に設計する必要があります。

ディクショナリがスレッド セーフを必要とする唯一の共有リソースであり、コードの他の部分がスレッド セーフである場合は、ロックの代わりにConcurrentDictionaryを使用することをお勧めします。

于 2012-10-03T07:04:53.070 に答える
2

メインオブジェクトがクラス内で完全に使用されていることが確実な場合は必要ありません。厳密に言えば、そうであっても必要ありませんが、変数が 2 のバージョンの方がはるかに簡単に推論できます。

  • コードを読む人は誰でも、メインオブジェクトが公開され、クラス外の何かによってロックされる可能性があるかどうかを考える必要はありません
  • ロック用の別のオブジェクトを使用したコードは、優れた実践に沿ったものに見えます
  • 偶発的/意図的に主要なオブジェクトを露出させた場合、より安全になります
于 2012-10-03T07:05:45.880 に答える