2012-01-30 3 views
2

나는 여러 스레드가 액세스하는 HashTable을 가지고있다. 예를 들어 세 개의 스레드를 살펴 보겠습니다.HashTable 동시성

스레드 A는 Hash.Insert ("a", 새 객체())를 수행합니다.

스레드 B는 Hash.Insert ("b", new object())를 수행합니다.

스레드 C는 Hash.Insert ("a", new object())를 수행합니다.

는 몇 가지 이유를 들어, 나는 순서에 대해주의를 해달라고하거나하는 과정의 끝에 해시에있을 것입니다 오브젝트 전체 해시

에 대한 잠금을 사용할 수 없습니다. 내가 신경 쓰는 유일한 점은 다른 스레드에서 동일한 셀을 업데이트하여 데이터가 손상되지 않는다는 것입니다.

내 옵션에는 어떤 것이 있습니까? 또는 문제가 아니며 HashTable 자체에서 처리하고 데이터를 그대로 유지합니다.

+0

"몇 가지 이유 때문에 전체 해시에서 잠금을 사용할 수 없습니다. 해당 요구 사항을 설명 할 수 있습니까? 그것은 단지 성과입니까? – CodesInChaos

+0

@CodeInChaos 동시에 수천 개의 요청이있을 수 있으므로 기아에 대해 걱정이됩니다. 잠금이 프로세서 시간을 얻지 못하는 스레드에 대해 가능한 것이기 때문입니다 ... –

+0

비 FIFO 때문에 기아가 발생할 가능성은 거의 없습니다. 잠금 처리.http://stackoverflow.com/questions/961869/is-there-a-synchronization-class-that-guarantee-fifo-order-in-c를 참조하십시오. 기아를 방지하는 FIFO 순서를 보장하는 동기화 객체에 대해. –

답변

5

당신은 같은 것을 사용하여 고려할 수 :

ConcurrentDictionary<string, object> Hash = new ConcurrentDictionary<string, object>(); 

을 System.Collections.Concurrent 네임 스페이스.

+0

그것에 대해 생각했지만 ConcurrentDictionary가 구현되는 방법에 따라 달라집니다. 해시 전체를 잠그고 있습니까? 아니면 더 정교합니까? –

+0

@Amit 구현체가 잠금이 없다고 확신하지만, 물론 구현의 세부 사항 일뿐입니다. 그러나 lockless와 locking 구현의 차이점을 직접 관찰 할 수있는 방법은 없습니다. – CodesInChaos

+0

리플렉터의 빠른보기에서 동시 사전은 버킷 잠금을 사용하고 여러 잠금이 있고 각 셀 수가 하나의 잠금을 갖는 것으로 보입니다. 희망이 충분하다. –

3

ConcurrentDictionary가 도움이 될 것입니다. 잠금이 해제되지는 않지만 특정 상황을 제외하고는 "해시 전체를 잠그지"않습니다.

두 개의 모음, 잠금 배열 및 해시 버킷 모음을 사용합니다.
잠금 버킷의 수는 동시성 수준을 설정하여 제어 할 수 있으며 초기 용량을 설정하여 해시 버킷의 초기 수를 제어 할 수 있습니다. (이들은 모두 생성자 매개 변수입니다).

잠금 배열의 각 버킷은 간단한 모듈로 해시를 사용하여 여러 개의 해시 버킷을 처리합니다.

유일한 시간 동시 사전 잠금은 모든 잠금 버킷이라는 것을 :

  1. 하여 해시 버킷의 크기를 조정.
  2. 공용 Keys 속성을 읽을 때.
  3. 공용 Values ​​속성을 읽을 때.
  4. 공용 Count 속성을 읽을 때.
  5. 공용 IsEmpty 속성을 읽을 때.
  6. 통화를 할 때().
  7. 직렬화 할 때.

크기 조정을 제외하고는 모두 쉽게 피할 수 있습니다.

사전에서 항목의 최대 개수를 예측할 수 있으면 크기를 조정할 필요가 없습니다.