2009-04-02 24 views
8

Trong đoạn mã sau:containsKey Chủ đề Safe

public class StringCache 
{ 
    private readonly object lockobj = new object(); 

    private readonly Dictionary<int, string> cache = new Dictionary<int, string>(); 

    public string GetMemberInfo(int key) 
    { 
     if (cache.ContainsKey(key)) 
      return cache[key]; 
     lock (lockobj) 
     { 
      if (!cache.ContainsKey(key)) 
       cache[key] = GetString(key); 
     } 
     return cache[key]; 
    } 

    private static string GetString(int key) 
    { 
     return "Not Important"; 
    } 
} 

1) là chủ đề containsKey an toàn không? IOW, điều gì sẽ xảy ra nếu phương thức đó đang thực hiện khi một luồng khác đang thêm thứ gì đó vào từ điển? 2) Đối với bộ nhớ cache trả về đầu tiên [key], có bất kỳ cơ hội nào mà nó có thể trả về một giá trị bị cắt xén không?

TIA,

MB

Trả lời

14

Các cố hữu an toàn thread của containsKey không quan trọng, vì không có đồng bộ giữa containsKey & cache [key].

Ví dụ:

if (cache.ContainsKey(key)) 
    // Switch to another thread, which deletes the key. 
    return cache[key]; 

MSDN là khá rõ ràng về điểm này:

Để cho phép các bộ sưu tập để được truy cập bởi nhiều chủ đề để đọc và văn bản, bạn phải thực hiện của riêng bạn đồng bộ hóa.

Để biết thêm thông tin, JaredPar đã đăng một bài đăng blog tuyệt vời tại http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx về bộ sưu tập chủ đề an toàn.

1

Đây là những gì nó nói trong tĩnh công cộng MSDN documentation:

(chung trong Visual Basic) thành viên của loại này là chủ đề an toàn. Bất kỳ thành viên cá thể nào cũng không được bảo đảm là luồng an toàn.

Một điển < (Tất < (TKey, TValue>)>) có thể hỗ trợ nhiều độc giả đồng thời, miễn là bộ sưu tập không được sửa đổi. Mặc dù vậy, liệt kê thông qua bộ sưu tập là về bản chất không phải là thủ tục an toàn theo luồng . Trong trường hợp hiếm hoi khi một số đếm cạnh tranh với việc ghi quyền truy cập, bộ sưu tập phải là bị khóa trong toàn bộ liệt kê. Để cho phép truy cập bộ sưu tập bằng nhiều chủ đề để đọc và viết , bạn phải thực hiện đồng bộ hóa của riêng mình.

Nếu tôi đọc chính xác, tôi không tin rằng đó là chủ đề an toàn.

5

Không, ContainsKey không an toàn theo chủ đề nếu bạn đang viết các giá trị trong khi đang cố gắng đọc.

Có, có khả năng bạn có thể lấy lại kết quả không hợp lệ - nhưng có thể bạn sẽ bắt đầu thấy ngoại lệ trước.

Hãy xem xét ReaderWriterLockSlim để khóa trong các tình huống như thế này - nó được xây dựng để thực hiện loại công cụ này.

1

Từ điển không phải là Chủ đề an toàn.

Nếu bạn nói rằng

những gì sẽ xảy ra nếu phương pháp đó là thực hiện khi thread khác là thêm một cái gì đó vào từ điển?

thì tôi cho rằng các chức năng khác cũng truy cập vào số cache. Bạn cần đồng bộ hóa các truy cập (đọc và viết) với số cache. Sử dụng đối tượng khóa của bạn trong tất cả các hoạt động này.

1

Tôi tin rằng nó không phải là thread an toàn,

tôi sẽ đề nghị đi qua bên dưới liên kết, nó cho thấy việc thực hiện các chủ đề từ điển an toàn, hoặc tốt hơn của nó để phát triển đồng bộ của riêng bạn.

http://lysaghtn.weebly.com/synchronised-dictionary.html

+0

Không tìm thấy liên kết (404). – avenmore

Các vấn đề liên quan