ConcurrentDictionary Pitfall - Are delegates factories from GetOrAdd and AddOrUpdate synchronized? AddOrUpdateはアトミックではないことを示しています(代理人が複数回実行されることは保証できません)。atomic addorupdate(同時辞書を使用して名前付きロッカーを作成しようとしています)
私は同時辞書ラhereを使用して実装をロック名を実装しようとしていますが、辞書は、このように、永遠に成長しないはずです。ここで
public class ConcurrentDictionaryNamedLocker : INamedLocker
{
// the IntObject values serve as the locks and the counter for how many RunWithLock jobs
// are about to enter or have entered the critical section.
private readonly ConcurrentDictionary<string, IntObject> _lockDict = new ConcurrentDictionary<string, IntObject>();
private static readonly IntObject One = new IntObject(1);
private readonly Func<string, IntObject, IntObject> _decrementFunc = (s, o) => o - 1;
private readonly Func<string, IntObject, IntObject> _incrementFunc = (s, o) => o + 1;
private readonly Func<string, IntObject> _oneFunc = s => new IntObject(1);
private readonly Func<string, IntObject> _zeroFunc = s => new IntObject(0);
public TResult RunWithLock<TResult>(string name, Func<TResult> body)
{
name = name.ToLower();
TResult toReturn;
lock (_lockDict.AddOrUpdate(name, _oneFunc, _incrementFunc))
{
toReturn = body();
if (!_lockDict.TryRemove(name, One))
_lockDict.AddOrUpdate(name, _zeroFunc, _decrementFunc);
}
return toReturn;
}
public void RunWithLock(string name, Action body)
{
name = name.ToLower();
lock (_lockDict.AddOrUpdate(name, _oneFunc, _incrementFunc))
{
body();
if (!_lockDict.TryRemove(name, One))
_lockDict.AddOrUpdate(name, _zeroFunc, _decrementFunc);
}
}
}
しかし、問題はAddOrUpdateがアトミックではないですだから、競合が起きたときにエントリが削除されないことがしばしばあります。私はかなり確信していますが、AddOrUpdateがアトミックな場合、上記のコードはその仕事を行い、エントリーは適切に削除されます。
hereと記載されているキー+値拡張メソッドTryRemove(key、val)による条件付き削除の使用に注目してください。また、IntObjectはintの簡単な可変オブジェクトラッパーです。
私のオプションは何ですか? 1.原子条件付き(キーと値による)削除を持つ並行ディクショナリ実装がありますか?2. AddOrUpdateはアトミックであり、デリゲートが複数回実行されないようにしますか?
他にアイデアはありますか?名前付きロッカーが高速であることを望みますが、無制限のロック名前空間が与えられても、与えられた名前ではあまり競合しないので、メモリ圧迫の問題はありません。私が知る限り、文字列インターンシップは名前によって永遠に成長し、決してクリーンアップされず、その他の副作用があります。ミューテックスは半スローで、さまざまな迷惑行為(260文字制限)があります。
あなたはこの答えで説明したように 'ConcurrentDictionary'とタイプされた辞書を使用する可能性があります。http://stackoverflow.com/a/12611341/1236734 –