Kolekcja bezpieczna wątkowo w porównaniu z kolekcją bez ochrony wątków może być postrzegana w inny sposób.
Rozważmy sklep bez sprzedawcy, z wyjątkiem kasy. Masz mnóstwo problemów, jeśli ludzie nie działają odpowiedzialnie. Na przykład, powiedzmy, że klient bierze puszkę z piramidy - może, podczas gdy urzędnik obecnie buduje piramidę, rozpętałoby się piekło. A co, jeśli dwóch klientów sięgnie po ten sam przedmiot w tym samym czasie, kto wygrywa? Czy będzie walka? To jest kolekcja bez ochrony wątków. Istnieje wiele sposobów na uniknięcie problemów, ale wszystkie wymagają pewnego rodzaju blokowania lub raczej jawnego dostępu w taki czy inny sposób.
Z drugiej strony, rozważ sklep z urzędnikiem przy biurku, a zakupy możesz robić tylko za jego pośrednictwem. Stajesz w kolejce i prosisz go o przedmiot, on przynosi ci go z powrotem, a ty wychodzisz z kolejki. Jeśli potrzebujesz wielu przedmiotów, możesz odebrać tylko tyle przedmiotów w każdej podróży w obie strony, ile pamiętasz, ale musisz uważać, aby nie zapychać urzędnika, to złości innych klientów w kolejce za tobą.
Teraz rozważ to. W sklepie z jednym urzędnikiem, co, jeśli dojdziesz do pierwszej linii i zapytasz sprzedawcę „Czy masz papier toaletowy”, a on powie „Tak”, a potem powiesz „Ok, ja” Skontaktuję się z Tobą, kiedy będę wiedział, ile potrzebuję ”, a gdy wrócisz na początek kolejki, sklep może oczywiście zostać wyprzedany. Ten scenariusz nie jest chroniony przez kolekcję z ochroną wątków.
Kolekcja z ochroną wątków gwarantuje, że jej wewnętrzne struktury danych są zawsze prawidłowe, nawet jeśli uzyskiwany jest do nich dostęp z wielu wątków.
Kolekcja bez ochrony wątków nie jest objęta żadnymi takimi gwarancjami. Na przykład, jeśli dodasz coś do drzewa binarnego w jednym wątku, podczas gdy inny wątek jest zajęty równoważeniem drzewa, nie ma gwarancji, że element zostanie dodany, a nawet, że drzewo będzie nadal ważne później, może być uszkodzone bez nadziei.
Kolekcja z ochroną wątków nie gwarantuje jednak, że wszystkie sekwencyjne operacje w wątku działają na tej samej „migawce” wewnętrznej struktury danych, co oznacza, że jeśli masz taki kod:
if (tree.Count > 0)
Debug.WriteLine(tree.First().ToString());
możesz otrzymać NullReferenceException, ponieważ pomiędzy tree.Count
a tree.First()
inny wątek wyczyścił pozostałe węzły w drzewie, co oznacza, First()
że powróci null
.
W tym scenariuszu musisz albo sprawdzić, czy dana kolekcja ma bezpieczny sposób na uzyskanie tego, czego chcesz, być może musisz przepisać powyższy kod lub może być konieczne zablokowanie.