Bộ sưu tập an toàn theo chủ đề so với bộ sưu tập không an toàn theo 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, trừ khi thanh toán. Bạn có rất nhiều vấn đề nếu mọi người không hành động có trách nhiệm. Ví dụ, giả sử một khách hàng lấy một lon từ một kim tự tháp có thể 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, điều gì xảy ra nếu hai khách hàng đến cùng một mục cùng một lúc, ai sẽ thắng? Sẽ có một cuộc chiến? Đây là bộ sưu tập không an toàn. 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 theo 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 làm việc và bạn chỉ có thể mua sắm qua anh ta. Bạn nhận được trong dòng, và hỏi anh ta cho một mục, ông mang nó lại cho bạn, và bạn đi ra khỏi dòng. Nếu bạn cần nhiều mặt hàng, bạn chỉ có thể nhận nhiều mặt hàng trên mỗi chuyến khứ hồi như bạn có thể nhớ, nhưng bạn cần phải 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 xếp hàng phía sau bạn.
Bây giờ hãy xem xét điều này. Trong cửa hàng với một nhân viên bán hàng, bạn sẽ làm gì nếu bạn đi đến phía trước của hàng và hỏi nhân viên bán hàng "Bạn có giấy vệ sinh nào không" và nói "Có", sau đó bạn "Ok, tôi" sẽ lấy lại cho bạn khi tôi biết bao nhiêu tôi cần ", sau đó bởi thời gian bạn trở lại ở phía trước của dòng, các cửa hàng có thể tất nhiên được bán ra. Kịch bản này không được ngăn chặn bởi một bộ sưu tập luồng.
Bộ sưu tập luồng an toàn đảm bảo rằng cấu trúc dữ liệu nội bộ của nó luôn hợp lệ, ngay cả khi được truy cập từ nhiều luồng.
Bộ sưu tập không an toàn không có bất kỳ bảo đảm nào như vậy. Ví dụ, nếu bạn thêm một cái gì đó vào cây nhị phân trên một sợi, trong khi một luồng khác đang bận tái cân bằng cây, không có gì đảm bảo mục sẽ được thêm vào, hoặc thậm chí cây đó vẫn còn hợp lệ sau đó, nó có thể bị hỏng ngoài hy vọng.
Một bộ sưu tập thread không, tuy nhiên, đảm bảo rằng các hoạt động tuần tự trên thread tất cả công việc trên cùng một "bản chụp" của cấu trúc dữ liệu nội bộ của mình, điều đó có nghĩa rằng 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ì inbetween tree.Count
và tree.First()
, một chủ đề khác đã xóa các nút còn lại trong cây, có nghĩa là First()
sẽ trả lại null
.
Đối với trường hợp này, bạn cần xem liệu bộ sưu tập đang đề cập có một cách an toàn để có được những gì bạn muốn, 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.
Bạn có thể muốn xem [Bài dự án mã này về đề tài này] (http: //www.codeproject.com/Articles/548406/Dictionary-plus-Locking-versus-ConcurrentDictionar) – nawfal