8

次のコードでは:

public class SomeItem { }
public class SomeItemsBag : ConcurrentBag< SomeItem > { }
public class SomeItemsList : List< SomeItem > { }
public static class Program
{
    private static ConcurrentDictionary< string, SomeItemsBag > _SomeItemsBag;
    private static ConcurrentDictionary< string, SomeItemsList > _SomeItemsList;

    private static void GetItem(string key)
    {
        var bag = _SomeItemsBag[key];
        var list= _SomeItemsList[key];
        ...
    }
}

私の仮定では、bag はスレッドセーフであり、list はそうではありません。これは、マルチスレッド アプリでリストの辞書を処理する正しい方法ですか?

追加するように編集: 1 つのスレッドのみがバッグ/リストに追加され、別のスレッドが削除されますが、多くのスレッドがアクセスできます。

4

1 に答える 1

2

ConcurrentBagはスレッドセーフであり、そうではないというあなたの仮定Listは正しいです。ただし、次のように、リストへのアクセスを同期できます。

private static ConcurrentDictionary< string, SomeItemsBag > _SomeItemsBag;
private static ConcurrentDictionary< string, SomeItemsList > _SomeItemsList;
private static object _someItemsListLocker = new object();

private static void GetItem(string key)
{
    var bag = _SomeItemsBag[key];
    lock (_someItemsListLocker) {
        var list = _SomeItemsList[key];
    }
}

ただし、使用するデータ構造についてより総合的なアドバイスが必要な場合は、状況を完全に説明することをお勧めします。リストよりも必要なものに適したものもあることConcurrentQueueに注意してください。ConcurrentStack追加と削除はそれぞれ一方の側 (スタックの場合は同じ側、キューの場合は反対側) でのみ発生するため、これらはマルチスレッド シナリオで最適化されます。

于 2012-05-01T21:13:30.227 に答える