2013-02-11 44 views
12

Với lớp sau đây:Nhiều đối tượng khóa cần thiết?

class x 
{ 
    Object lockOne = new Object(); 
    Object lockTwo = new Object(); 

    List<Something> listOne = new List<Something>(); 
    List<Something> listTwo = new List<Something>(); 

    void MethodOne() 
    { 
     lock(lockOne) 
     { 
      // some operation on listOne 
     } 
    } 

    void MethodTwo() 
    { 
     lock(lockTwo) 
     { 
      // some operation on listTwo 
     } 
    } 
} 

Là nó đúng để sử dụng hai đối tượng khóa giả định rằng MethodOne()MethodTwo() thể được gọi từ chủ đề khác nhau đồng thời lưu ý rằng listOnelistTwo không liên quan trong anyway. Các hoạt động duy nhất liên quan đến khóa là những hoạt động được nêu trong các chú thích ở trên.

+1

Nó được gọi là tách khóa và là cách tốt để giảm ganh đua nếu hai đối tượng và phương pháp độc lập. – assylias

+0

Nó nên được gọi là cảm giác thông thường, làm theo cách khác xung quanh là một thực hành rất xấu. – Dariusz

+0

Một điều bạn có thể muốn xem xét là sử dụng [ReaderWriterLock] (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx). Nếu bạn chỉ đọc từ danh sách nó cho phép nhiều chủ đề sử dụng nó cùng một lúc ('List' có chủ đề đọc an toàn), một khi bạn cần viết bạn nâng cấp khóa và sau đó chỉ có một luồng có thể ghi và tất cả các độc giả bị chặn, sau đó nhiều người đọc có thể bắt đầu lại. –

Trả lời

7

Vâng, đúng. Nó tránh không cần khóa một danh sách chỉ vì danh sách khác đang được thực hiện.

+2

Chính xác? Vâng. Wasteful? Ngoài ra có, không có nhu cầu cho các đối tượng khóa riêng biệt ở đây. – svick

+4

Để làm rõ những gì svick nói, ông không nói để khóa trên một đối tượng khóa duy nhất nhưng [không sử dụng bất kỳ đối tượng khóa ở tất cả] (http://stackoverflow.com/a/14814386/80274) và khóa trên danh sách chính nó . –

6

Không cần các đối tượng khóa riêng biệt ở đây. Mã sau đây cũng sẽ hoạt động tốt, với ít mã hơn, ít chi phí hơn và ít cơ hội sử dụng sai mã khóa sai:

class x 
{ 
    List<Something> listOne = new List<Something>(); 
    List<Something> listTwo = new List<Something>(); 

    void MethodOne() 
    { 
     lock (listOne) 
     { 
      // some operation on listOne 
     } 
    } 

    void MethodTwo() 
    { 
     lock (listTwo) 
     { 
      // some operation on listTwo 
     } 
    } 
} 
+10

Cũng giống như một lưu ý, thực hành tốt nhất (như hiển thị này) là chỉ khóa các mục là 'riêng tư 'cho lớp - nếu không bạn không biết mã bên ngoài có thể cố khóa nó khi nào và gây ra deadlocks hoặc điều kiện chủng tộc . –

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