Một bộ sưu tập an toàn chủ đề so với một bộ sưu tập không an toàn chủ đề có thể được xem xét theo một cách khác.
Hãy xem xét một cửa hàng không có nhân viên bán hàng, ngoại trừ lúc thanh toán. Bạn có vô số vấn đề nếu mọi người không hành động có trách nhiệm. Chẳng hạn, giả sử một khách hàng lấy một lon từ kim tự tháp trong khi một nhân viên bán hàng hiện đang xây dựng kim tự tháp, tất cả địa ngục sẽ vỡ ra. Hoặc, nếu hai khách hàng tiếp cận cùng một mặt hàng cùng một lúc, ai sẽ thắng? Sẽ có một cuộc chiến? Đây là một bộ sưu tập không chủ đề. Có rất nhiều cách để tránh các vấn đề, nhưng tất cả chúng đều yêu cầu một số loại khóa, hoặc truy cập rõ ràng hơn bằng cách này hay cách khác.
Mặt khác, hãy xem xét một cửa hàng với một nhân viên bán hàng tại bàn và bạn chỉ có thể mua sắm thông qua anh ta. Bạn xếp hàng, và yêu cầu anh ta cho một món đồ, anh ta mang nó lại cho bạn, và bạn đi ra khỏi hàng. Nếu bạn cần nhiều mặt hàng, bạn chỉ có thể nhặt được bao nhiêu mặt hàng trên mỗi vòng mà bạn có thể nhớ, nhưng bạn cần cẩn thận để tránh làm phiền nhân viên bán hàng, điều này sẽ khiến các khách hàng khác đứng sau bạn.
Bây giờ hãy xem xét điều này. Trong cửa hàng có một nhân viên bán hàng, điều gì sẽ xảy ra nếu bạn đi hết hàng trước và hỏi nhân viên bán hàng "Bạn có giấy vệ sinh nào không" và anh ta nói "Có", rồi bạn nói "Ok, tôi ' sẽ quay lại với bạn khi tôi biết tôi cần bao nhiêu ", sau đó khi bạn quay lại đầu hàng, cửa hàng tất nhiên có thể được bán hết. Kịch bản này không được ngăn chặn bởi một bộ sưu tập chủ đề.
Một bộ sưu tập chủ đề đảm bảo rằng cấu trúc dữ liệu bên trong của nó luôn hợp lệ, ngay cả khi được truy cập từ nhiều luồng.
Một bộ sưu tập không an toàn không đi kèm với bất kỳ đảm bảo như vậy. Chẳng hạn, nếu bạn thêm một cái gì đó vào cây nhị phân trên một luồng, trong khi một luồng khác đang bận cân bằng lại cây, thì không có gì đảm bảo vật phẩm sẽ được thêm vào, hoặc thậm chí cây vẫn còn hiệu lực sau đó, nó có thể bị hỏng ngoài hy vọng.
Tuy nhiên, một bộ sưu tập luồng không đảm bảo rằng các hoạt động tuần tự trên luồng đều hoạt động trên cùng một "ảnh chụp nhanh" của cấu trúc dữ liệu bên trong của nó, điều đó có nghĩa là nếu bạn có mã như thế này:
if (tree.Count > 0)
Debug.WriteLine(tree.First().ToString());
bạn có thể nhận được một NullReferenceException vì giữa tree.Count
và tree.First()
, một luồng khác đã xóa các nút còn lại trong cây, có nghĩa là First()
sẽ trả về null
.
Đối với kịch bản này, bạn cần phải xem liệu bộ sưu tập được đề cập có cách an toàn để có được những gì bạn muốn hay không, có lẽ bạn cần phải viết lại mã ở trên, hoặc bạn có thể cần phải khóa.