2012-07-17 13 views
19

Tôi có báo cáo kết quả Khóa sau:Biến khóa có nên được khai báo dễ bay hơi không?

private readonly object ownerLock_ = new object(); 

lock (ownerLock_) 
{ 
} 

Tôi có nên sử dụng volatile từ khóa cho biến khóa của tôi?

private readonly volatile object ownerLock_ = new object(); 

Trên MSDN tôi thấy nó thường được sử dụng cho trường được truy cập không khóa, vì vậy nếu tôi sử dụng Khóa, tôi không cần sử dụng dễ bay hơi?

Từ MSDN:

Các modifier dễ bay hơi thường được sử dụng cho một lĩnh vực được truy cập bởi nhiều chủ đề mà không cần sử dụng câu lệnh khóa để serialize truy cập.

+0

Chúng ta cần nhiều ngữ cảnh hơn thế này để trả lời câu hỏi. Khóa này tồn tại ở đâu trong mối quan hệ với các đối tượng sử dụng khóa? –

+3

Đó chắc chắn là chủ đề an toàn vì nó hiện đang tồn tại. Bạn không thể đảm bảo khi bạn thêm mã trong khối khóa {}. –

+0

Bạn không cần phải khóa một đối tượng 'readonly' ... trong đó nó là' readonly' ... – NominSim

Trả lời

18

Nếu bạn chỉ bao giờ truy cập vào dữ liệu mà khóa "bảo vệ" trong khi bạn sở hữu khóa, sau đó có - làm cho những lĩnh vực không ổn định là không cần thiết. Bạn không cần phải biến biến số ownerLock_ dễ bay hơi. (Hiện tại bạn không hiển thị bất kỳ mã thực tế nào trong câu lệnh lock, điều này khiến khó nói về các thuật ngữ cụ thể - nhưng tôi giả sử bạn muốn thực sự là đang đọc/sửa đổi một số dữ liệu trong câu lệnh lock.)

volatile phải là rất hiếm khi được sử dụng trong mã ứng dụng. Nếu bạn muốn truy cập không có khóa vào một biến duy nhất, thì Interlocked hầu như luôn đơn giản hơn. Nếu bạn muốn truy cập không bị khóa ngoài đó, tôi hầu như luôn luôn bắt đầu khóa. (Hoặc cố gắng sử dụng các cấu trúc dữ liệu không thay đổi để bắt đầu.)

Tôi chỉ mong đợi để xem volatile trong mã đang cố gắng xây dựng mức trừu tượng cao hơn cho luồng - ví dụ như trong mã TPL. Nó thực sự là một công cụ cho các chuyên gia người thực sự thực sự hiểu mô hình bộ nhớ .NET kỹ lưỡng ... trong số đó có rất ít, IMO.

+0

Cảm ơn bạn đã trả lời nhanh chóng của bạn, Cho phép nói rằng tôi đang sử dụng chỉ Khóa, có vẻ như hiếm nhưng có thể 2 chủ đề mà sẽ đi đến khóa tuyên bố cả hai sẽ kiểm tra nhà nước ownerLock_ cùng một lúc và cố gắng khóa nó hoặc mỗi khác? Tôi hỏi câu hỏi này bởi vì tôi đã có vấn đề với khóa trong mã của tôi và tôi nghĩ rằng nó liên quan đến vấn đề này. –

+0

@DorCohen: Chỉ một trong số họ sẽ có được khóa tại một thời điểm. Sau đó nó sẽ thực hiện phần thân của câu lệnh 'lock' và khi nó giải phóng khóa, luồng khác sẽ có thể lấy khóa và thực thi mã. –

+0

@DorCohen, có vẻ như vấn đề của bạn không phải là những gì bạn đang khóa, nhưng những gì bạn đang cố gắng làm trong cơ thể khóa. –

2

Nếu có gì đó là readonly thì đó là chủ đề an toàn, thời gian. (Vâng, gần như. Một chuyên gia có thể có thể tìm ra cách để có được một NullReferenceException trên tuyên bố lock của bạn, nhưng nó sẽ không dễ dàng.) Với readonly bạn không cần volatile, Interlocked hoặc khóa. Đó là từ khóa lý tưởng cho đa luồng, và bạn nên sử dụng nó ở bất cứ đâu bạn có thể. Nó hoạt động tuyệt vời cho một đối tượng khóa mà bất lợi lớn của nó (bạn không thể thay đổi giá trị) không quan trọng.

Ngoài ra, trong khi tham chiếu là không thay đổi, đối tượng được tham chiếu có thể không. "đối tượng mới()" có ở đây, nhưng nếu đó là số List hoặc thứ gì đó khác có thể thay đổi - và không an toàn theo chủ đề - bạn sẽ muốn khóa tham chiếu (và tất cả các tham chiếu khác, nếu có) để giữ các đối tượng thay đổi trong hai chủ đề cùng một lúc.