2013-06-04 2 views
2

그래서, 내가 가지고 Dictionary<KType,VType> Foo

스레드 하나에있어 자체 안전 TryGetValue 스레드입니다.

이렇게 잠그려면 얼마가 필요합니까? 내가 좋아하는 뭔가를 할 수 있습니다 :

void Thread1() { 
    ... 
    if (!Foo.TryGetValue(key, out v)) { 
    lock (syncobj) { 
     Foo.Add(new VType()); 
    } 
    } 
    ... 
} 
void Thread2() { 
    ... 
    lock (syncobj) { 
    Foo.TryGetValue(key, out v)) 
    } 
    ... 
} 

을 Thread1 프로그램 계산의 90 %와 TryGetValue 여러 번이라고합니다. 따라서, 매번 잠금을 호출하지 않아도됩니다. 업데이 트가 TryGetValue이 실행되는 동시에 다른 스레드에서 발생할 수있는 어떤 기회가 있다면

+5

이게 있습니다 : http://msdn.microsoft.com/en-us/library/dd287191.aspx – asawyer

+0

와우 ... 나는 Google에서 그것을 찾지 못했고 나는 또한 찾고있었습니다. 내가 본 모든 것은 2010 년 이전이라고 생각합니다. – Jay

답변

5

당신은 lock에 모든 시간을.

TryGetValue은 서로 간섭하지 않습니다 TryGetValue를 호출하는 다중 스레드, 자체와 스레드 안전합니다. 그러나 어떤 스레드가 Add을 호출하고 다른 스레드가 을 수행하는 경우 사전을 사용하면 손상 될 가능성이 있습니다.

그렇다면 자물쇠가 끔찍하지 않을 수도 있습니다. TryGetValue은 "여러 번"이라고하지만, 얼마나 자주 말하지는 않습니다. 더 중요한 것은 갈등이 얼마나 자주 일어날 지 말하지 않습니다. Uncontended lock은 현대 하드웨어에서 50 나노초 같은 것을 소비 할 것이므로 거대한 비용이 아닙니다. 잠금 기능을 사용하여 잠금 기능을 수행 할 수 있습니다. ReaderWriterLockSlim을 고려해 볼 수도 있습니다.

읽기 작업은 잠금없이 수행되지만, ConcurrentDictionary은 잠금없는 데이터 구조가 아닙니다. 그것은 일 수도 있습니다 귀하의 상황에서 더 나은 수행 (아마),하지만 주어진 아니에요.

+0

니스 (Nice to know)는 필요 이상으로 호기심을 불러 일으켰습니다. 나는 스피드의 "이유"를 가지고 질문을 정당화하려고 노력했다. 'ConcurrentDictionary'는 그것을하는 "옳은"방법 인 것처럼 보입니다. (적어도 그것의 더 우아한 방법 IMO). – Jay

+0

실제로, 'Dictionary'는 [ReaderWriterLockSlim] (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx)의 예제 사용 사례입니다. –