사전에 주어진 키에 대한 값이 포함되지 않은 경우에만 false를 반환하거나 다른 스레드가 무언가를 추가 / 업데이트하는 것처럼 스레드 경합 상태로 인해 false를 반환할까요?
코드 질문 :
ConcurrentDictionary<int, string> cd = new ConcurrentDictionary<int, string>();
// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one");
// Will this ever fail if no other thread ever removes with the key value of 1?
cd.TryRemove(1);
편집 :
주어진 키에 대한 값이 포함되어 있지 않은 경우에만 false를 반환한다고 생각하지만 절대적으로 확신하고 싶습니다.
답변
하지만 미치 권리 A는 것을 ConcurrentDictionary
경쟁 조건에 취약하지 않습니다, 나는 당신이 묻는 질문에 대한 대답은 키가있는 경우 네는 것을 생각 TryRemove
작동하며 돌아갑니다 true
.
게시 한 코드에서는 다른 곳에서는 액세스 할 수없는 지역 변수 이므로 TryRemove
반환 할 방법이 없습니다. 그러나 다른 코드에이 객체에 대한 참조가 주어지고 별도의 스레드에서 키를 제거하는 경우 여기에서도를 반환 할 수 있습니다. 그러나 다른 작업이 수행되고 있기 때문 이 아니라 키가 이미 제거 되었기 때문입니다. 사전과 키는 어떻게 든 거기에 “고정”되어 있습니다.false
cd
ConcurrentDictionary
TryRemove
false
답변
ConcurrentDictionary는 경쟁 조건에서 고통을하지 않습니다. 그것이 당신이 그것을 사용하는 이유입니다.
반환 값
개체가 성공적으로 제거 된 경우 true이고, 그렇지 않으면 거짓입니다.
답변
또 하나의 요점 :
// This might fail if another thread is adding with key value of 1.
cd.TryAdd(1, "one");
이 의견은 정확하지 않으며 ‘시도’가 의미하는 바에 대해 동일한 오해가있을 수 있습니다. 동시에 추가하려는 시도가 아니라 key로 값이 이미 추가되었는지 여부 1
입니다.
표준을 고려하십시오 Dictionary<TKey,TValue>
. 동등한 코드는 다음과 같습니다.
if (!d.Contains(1))
d.Add(1, "one");
두 가지 작업이 필요합니다. 로 스레드가 안전하려면 이러한 API를 설계 할 수있는 방법은 없습니다 cd
키 값이있을 수 있습니다 1
받는 호출 사이에 추가 Contains
하고 Add
다음 초래, Add
던지고.
동시 컬렉션에는 이러한 테스트 및 수행 쌍을 단일 API 뒤에있는 단일 원자 작업으로 논리적으로 묶는 API가 있습니다.