스레드 세이프 콜렉션과 비스 레드 세이프 콜렉션은 다른 방식으로 볼 수 있습니다.
계산대를 제외하고 점원이없는 상점을 고려하십시오. 사람들이 책임감있게 행동하지 않으면 많은 문제가 있습니다. 예를 들어, 고객이 피라미드 캔에서 캔을 가져 가고 있지만 점원이 현재 피라미드를 짓고 있다면 모든 것이 망가질 것입니다. 또는 두 명의 고객이 동시에 같은 상품을 구매하면 누가 이기는가? 싸움이 있을까요? 이것은 스레드로부터 안전하지 않은 콜렉션입니다. 문제를 피할 수있는 방법은 많이 있지만, 모두 일종의 잠금 또는 어떤 방식 으로든 명시적인 액세스가 필요합니다.
반면에 책상에 점원이있는 상점을 생각해보십시오. 상점을 통해서만 쇼핑 할 수 있습니다. 당신은 줄을 서서 그에게 물건을 요구하고, 그는 그것을 당신에게 가져오고, 당신은 줄을 벗어납니다. 여러 개의 물품이 필요한 경우, 각 왕복에서 기억할 수있는만큼만 물품을 수령 할 수 있지만, 점원의 호그를 피하지 않도록주의해야합니다. 이렇게하면 다른 고객이 뒤에서 줄을 서게됩니다.
이제 이것을 고려하십시오. 점원 한 명이있는 상점에서 줄 앞에 줄을 서서 점원에게 "화장지가 있습니까?"라고 물으면 "예"라고 말한 다음 "좋아요." "내가 얼마나 필요한지 알면 다시 연락 할 것입니다."그런 다음 줄 앞에서 돌아올 때마다 매장을 매진 할 수 있습니다. 이 시나리오는 스레드 세이프 컬렉션에 의해 방지되지 않습니다.
스레드 세이프 컬렉션은 내부 데이터 구조가 여러 스레드에서 액세스 된 경우에도 항상 유효한지 확인합니다.
스레드로부터 안전하지 않은 콜렉션에는 그러한 보장이 제공되지 않습니다. 예를 들어, 하나의 스레드에서 이진 트리에 무언가를 추가하고 다른 스레드가 트리를 재조정하는 데 바쁘지만 항목이 추가되거나 그 후에도 여전히 트리가 유효하다는 보장은 없습니다. 희망을 넘어서 손상 될 수 있습니다.
그러나 스레드 세이프 컬렉션은 스레드에 대한 순차적 작업이 모두 내부 데이터 구조의 동일한 "스냅 샷"에서 작동한다는 것을 보증하지 않습니다. 이는 다음과 같은 코드가있는 경우를 의미합니다.
if (tree.Count > 0)
Debug.WriteLine(tree.First().ToString());
당신은 inbetween 때문에 NullReferenceException이를 얻을 수 있습니다 tree.Count
및 tree.First()
다른 스레드 수단이 나무의 나머지 노드 없애 게했다, First()
반환됩니다 null
.
이 시나리오의 경우 해당 컬렉션에 원하는 것을 얻을 수있는 안전한 방법이 있는지 확인해야합니다. 위의 코드를 다시 작성해야하거나 잠 가야 할 수도 있습니다.