2008-09-20 27 views

Trả lời

52

Cập nhật - trong .NET 4, hiện nay là ConcurrentQueue<T> trong System.Collections.Concurrent, như tài liệu ở đây http://msdn.microsoft.com/en-us/library/dd267265.aspx. Thật thú vị khi lưu ý rằng phương thức IsSynchronized của nó (đúng) trả về false.

ConcurrentQueue<T> viết lại hoàn toàn, tạo bản sao của hàng đợi để liệt kê và sử dụng các kỹ thuật không khóa nâng cao như Interlocked.CompareExchange()Thread.SpinWait().

Phần còn lại của câu trả lời này vẫn có liên quan trong khi nó liên quan đến sự sụp đổ của các thành viên Synchronize() và SyncRoot cũ và tại sao chúng không hoạt động tốt từ phối cảnh API.


Theo nhận xét của Zooba, nhóm nghiên cứu BCL quyết định rằng quá nhiều nhà phát triển được hiểu lầm mục đích của Đồng bộ hóa (và đến một mức độ thấp hơn, SyncRoot)

Brian Grunkemeyer mô tả này trong nhóm BCL blog của một cặp vợ chồng của năm trở lại: http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx

Vấn đề chính là nhận được độ chi tiết chính xác xung quanh khóa, nơi một số nhà phát triển ngây thơ sử dụng nhiều thuộc tính hoặc phương pháp trên bộ sưu tập "đồng bộ" và tin rằng mã của họ là an toàn. Brian sử dụng Hàng đợi làm ví dụ của mình,

if (queue.Count > 0) { 
    object obj = null; 
    try { 
     obj = queue.Dequeue(); 

Nhà phát triển sẽ không nhận ra rằng Đếm có thể bị thay đổi bởi một chuỗi khác trước khi Dequeue được gọi.

Buộc các nhà phát triển sử dụng tuyên bố khóa rõ ràng xung quanh toàn bộ hoạt động có nghĩa là ngăn chặn cảm giác an toàn sai lệch này.Khi Brian đề cập, việc loại bỏ SyncRoot một phần vì nó chủ yếu được giới thiệu để hỗ trợ Đồng bộ hóa, nhưng cũng bởi vì trong nhiều trường hợp, có sự lựa chọn tốt hơn đối tượng khóa - phần lớn thời gian, hoặc là bản thân Hàng đợi, hoặc một

private static object lockObjForQueueOperations = new object(); 

trên lớp sở hữu trường hợp của Queue ...

tiếp cận thứ hai này thường là an toàn nhất vì nó tránh được một số bẫy phổ biến khác:

Khi họ nói, threading is hard, và làm cho nó có vẻ dễ dàng có thể nguy hiểm.

+0

Tôi không đồng ý với lời khuyên của bạn. Thật thú vị là tài liệu khóa của MSDN nói "Thông thường, biểu thức sẽ là" http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.71%29.aspx – dvogel

+2

Vâng, chúng đã sai với nó. NET 1.1 doco, hãy xem phiên bản .NET 4 mới nhất để sửa chữa ... http://msdn.microsoft.com/en-us/library/c5kehkcz(v=VS.100).aspx –

+0

lý do tại sao đây là đối tượng tĩnh – Svisstack

0

(tôi giả sử bạn có nghĩa là Queue <T> cho một giây.)

Tôi không thể trả lời câu hỏi đặc biệt, ngoại trừ việc các thuộc tính IsSynchronized và SyncRoot (nhưng không phải Đồng bộ hóa() một cách rõ ràng) đều được thừa hưởng từ giao diện ICollection. Không có bộ sưu tập chung nào sử dụng tính năng này và giao diện ICollection <T> không bao gồm SyncRoot.

Vì lý do không được bao gồm, tôi chỉ có thể suy đoán rằng chúng không được sử dụng theo cách mà nhà thiết kế thư viện dự định hoặc đơn giản là không được sử dụng đủ để biện minh cho việc giữ chúng trong các bộ sưu tập mới hơn.

7

Bạn có thể tìm thấy giá trị CTP song song đang kiểm tra; đây là một blog entry từ những kẻ đang đặt nó lại với nhau đó là khá chuyên đề:

Enumerating Concurrent Collections

Nó không hẳn là điều tương tự, nhưng nó có thể giải quyết vấn đề lớn hơn của bạn. (Họ thậm chí sử dụng Queue<T> so ConcurrentQueue<T> như tấm gương của họ.)

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