2012-05-17 940 views
5

tôi hy vọng các mã sau vào bế tắc khi rõ ràng cố gắng để khóa trên cùng một đối tượng mà xây dựng đã bị khóa:Tại sao mã bế tắc này lại không?

void Main() 
{ 
    (new SiteMap()).Build(); 
} 

class SiteMap 
{ 
    private readonly object _lock = new object(); 

    public void Build() 
    { 
     lock (_lock) 
     { 
      Clear(); 

      Console.WriteLine("Build"); 
     } 
    } 

    public void Clear() 
    { 
     lock (_lock) 
     { 
      Console.WriteLine("Clear"); 
     } 
    } 
} 

Output:

Rõ ràng

Build

Sửa 1

Cảm ơn tất cả các bạn đã trả lời.

Nếu tôi thêm một cuộc gọi để xây dựng bên trong khóa của Clear (giữ phần còn lại của các mã giống nhau):

public void Clear() 
{ 
    lock (_lock) 
    { 
     Build(); 

     Console.WriteLine("Clear"); 
    } 
} 

Một bế tắc không xảy ra (hoặc ít nhất đó là những gì tôi nghĩ, LINQ Pad treo).

Theo câu trả lời của bạn, điều này sẽ không xảy ra, bởi vì nó vẫn là cùng một chuỗi.

Cảm ơn!

+1

Xem http://www.albahari.com/threading/part2.aspx, trong "Khóa lồng nhau". –

Trả lời

8

Trong C#, một chủ đề đang giữ khóa có thể nhập cùng một khóa mà không bị chặn.

Tuyên bố lock, cũng như Monitor class mà trên đó nó được tạo, là reentrant trong .NET.


Chỉnh sửa để đáp ứng với chỉnh sửa của bạn:

Khi bạn thêm các cuộc gọi đến Build bên trong rõ ràng, mã số không bế tắc - đó là tự xưng là đệ quy. Nó không phải chặn, nhưng thay vì chạy mãi mãi (cho đến khi, cuối cùng, bạn nhấn một StackOverflowException), bởi vì Build cuộc gọi Clear trong đó kêu gọi Build một lần nữa kêu gọi Clear, vv ....

+0

Về chỉnh sửa của tôi, tôi thực sự không biết làm thế nào tôi đã không nhìn thấy điều đó. Cảm ơn cả hai câu trả lời! – stacker

4

Tôi sẽ không vì rõ ràng được gọi trong cùng một chuỗi đã áp dụng khóa.

5

Các tài liệu cho lock nói:

Nếu một chuỗi khác cố gắng nhập mã bị khóa, nó sẽ chờ (chặn) cho đến khi đối tượng được nhả ra.

Từ khóa là "khác". Một luồng không tự khóa, chỉ là các luồng khác. Nếu một chuỗi khác đã sở hữu khóa, thì lock sẽ chặn.

Điều này tiết kiệm rất nhiều cơn đau đầu.