2012-02-08 26 views
5

Nếu tôi cóỔ khóa tĩnh có hoạt động trên các lớp trẻ em khác nhau không?

abstract class Parent 
{ 
    static object staticLock = new object(); 

    public void Method1() 
    { 
     lock(staticLock) 
     { 
      Method2(); 
     } 
    } 

    protected abstract Method2(); 
} 

class Child1 : Parent 
{ 
    protected override Method2() 
    { 
      // Do something ... 
    } 
} 

class Child2 : Parent 
{ 
    protected override Method2() 
    { 
      // Do something else ... 
    } 
} 

cuộc gọi đến new Child1().Method1()new Child2().Method1() sẽ sử dụng khóa giống nhau không?

+0

Và staticLock là "riêng tư" (mặc định cho các thành viên http://msdn.microsoft.com/en-us/library/ms173121.aspx), do đó không thể truy cập được bởi các lớp con. –

+0

@AlexeiLevenkov Tôi chỉ muốn bảo đảm rằng chỉ có một 'Method2' đang được gọi vào bất kỳ khoảnh khắc nào, tôi không cần các lớp con truy cập nó. –

+1

@JohnSaunders: Tôi không theo dõi bạn. Ý tưởng ở đây là có phương thức * công khai * * không thể ghi đè * để đảm bảo rằng * người gọi * luôn lấy khóa. Bằng cách đó, các tác giả của các lớp dẫn xuất có thể thực hiện Method2 mà không cần phải nhớ "oh yeah, tôi phải lấy khóa ở đây". Mô hình này loại bỏ một loại lỗi nhưng tất nhiên nó tạo ra cơ hội cho người khác; bây giờ các tác giả của các lớp dẫn xuất đó cần biết rằng khóa lớp cha được lấy và không gây ra bế tắc trên đó. –

Trả lời

15

Có. Một lớp dẫn xuất không nhận được mới bản sao dữ liệu tĩnh từ lớp cơ sở.

Tuy nhiên, đây không phải là trường hợp với các lớp học chung. Nếu bạn nói:

class Base<T> 
{ 
    protected static object sync = new object(); 
    ... 
} 

class Derived1 : Base<int> { ... } 
class Derived2 : Base<int> { ... } 
class Derived3 : Base<string> { ... } 
class Derived4 : Base<string> { ... } 
class Derived5 : Base<object> { ... } 
class Derived6 : Base<object> { ... } 

trường hợp Derived1 và Derived2 có cùng một đối tượng đồng bộ. Các cá thể của Derived3 và Derived4 có cùng một đối tượng đồng bộ. Các cá thể của Derived5 và Derived6 có cùng một đối tượng đồng bộ. Nhưng ba đối tượng đồng bộ là tất cả các đối tượng khác nhau.

+2

Eric, vì mã chung được jitted một lần cho tất cả các kiểu tham chiếu, điều đó có nghĩa là 'class Derived4: Base {...}' sẽ chia sẻ cùng một đối tượng đồng bộ với 'Derived3'? – phoog

+4

@phoog: Câu hỏi hay. Không; các công trình xây dựng khác nhau của một loại chung chung là * các loại khác nhau *. 'Base ' và 'Base ' là các kiểu khác nhau, do đó, 'Base .sync' và' Base .sync' là các trường khác nhau.Thực tế là như một chi tiết thực hiện, jitter sẽ jit các * phương pháp * của 'Base ' và 'Base ' một lần và tái sử dụng trạng thái jitted không thay đổi thực tế rằng chúng là * loại khác nhau *. –

+0

Cảm ơn Eric, ý tưởng rằng 'Base .sync' và' Base .sync' có thể là cùng một trường khá đáng lo ngại. – phoog

2

Có, nói chung, lock trên static đối tượng bảo vệ dữ liệu cho tất cả các phiên bản của lớp học của bạn.

Từ MSDN:

thực hành tốt nhất là để xác định một đối tượng riêng để khóa trên, hay biến đối tượng tĩnh riêng để bảo vệ dữ liệu chung cho tất cả các trường hợp.

2

Để thêm vào câu trả lời của ken2k: [Có] ... trừ khi được đánh dấu là [ThreadStatic] (rõ ràng không phải là trường hợp ở đây).

+0

Tôi không biết điều đó. Rất quan trọng đối với một vấn đề khác mà tôi đã giải quyết. –

+2

Thật vậy, một khóa tĩnh chủ đề sẽ thay vì đánh bại mục đích của việc có khóa ở nơi đầu tiên! –

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