문제

Queue.Synchronize를 호출하여 스레드로부터 안전한 큐 개체를 얻을 수 있지만 Queue<T>에서는 동일한 메서드를 사용할 수 없다는 것을 알았습니다.이유를 아는 사람 있나요?좀 이상한 것 같습니다.

도움이 되었습니까?

해결책

업데이트 - .NET 4에는 이제 ConcurrentQueue<T> 여기에 설명된 대로 System.Collections.Concurrent에서 http://msdn.microsoft.com/en-us/library/dd267265.aspx.IsSynchronized 메서드가 (올바로) false를 반환한다는 점이 흥미롭습니다.

ConcurrentQueue<T> 열거할 대기열의 복사본을 생성하고 다음과 같은 고급 잠금 없음 기술을 사용하여 완전히 처음부터 다시 작성합니다. Interlocked.CompareExchange() 그리고 Thread.SpinWait().

이 답변의 나머지 부분은 이전 동기화() 및 SyncRoot 멤버의 종료와 API 관점에서 잘 작동하지 않은 이유와 관련된 한 여전히 관련이 있습니다.


Zooba의 의견에 따르면 BCL 팀은 너무 많은 개발자가 동기화(및 그 이하의 경우 SyncRoot)의 목적을 오해하고 있다고 결정했습니다.

Brian Grunkemeyer는 몇 년 전 BCL 팀 블로그에서 이에 대해 다음과 같이 설명했습니다.http://blogs.msdn.com/bclteam/archive/2005/03/15/396399.aspx

핵심 문제는 잠금에 대한 올바른 세분성을 얻는 것입니다. 일부 개발자는 "동기화된" 컬렉션에서 여러 속성이나 메서드를 순진하게 사용하고 자신의 코드가 스레드로부터 안전하다고 믿습니다.Brian은 Queue를 예로 사용합니다.

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

개발자는 Dequeue가 호출되기 전에 다른 스레드에 의해 Count가 변경될 수 있다는 사실을 인식하지 못합니다.

개발자가 전체 작업에 대해 명시적인 잠금 문을 사용하도록 강제하는 것은 이러한 잘못된 보안 감각을 방지하는 것을 의미합니다.

Brian이 언급했듯이 SyncRoot를 제거한 이유 중 하나는 주로 동기화를 지원하기 위해 도입되었기 때문이기도 하지만 많은 경우 더 나은 잠금 개체 선택이 있기 때문이기도 합니다. 대부분의 경우 Queue 인스턴스 자체 또는

private static object lockObjForQueueOperations = new object();

대기열의 인스턴스를 소유한 클래스에서...

후자의 접근 방식은 일반적으로 다른 일반적인 함정을 피하므로 가장 안전합니다.

그들이 말했듯이, 스레딩이 어렵다, 쉬운 것처럼 보이게 만드는 것은 위험할 수 있습니다.

다른 팁

확인해 볼 가치가 있는 병렬 CTP를 찾을 수도 있습니다.여기에 꽤 시사적인 내용을 담은 블로그 항목이 있습니다.

동시 컬렉션 열거

완전히 똑같은 것은 아니지만 더 큰 문제를 해결할 수도 있습니다.(그들은 심지어 Queue<T> ~ 대 ConcurrentQueue<T> 그들의 예로서.)

이제 .Net 4.0에 하나가 있습니다.

ConcurrentQueue<T> 

System.Collections.Concurrent에서

http://msdn.microsoft.com/en-us/library/dd267265.aspx

(두 번째 항목에 대해서는 Queue<T>를 의미한다고 가정합니다.)

IsSynchronized 및 SyncRoot 속성(명시적으로 동기화()는 아님)이 ICollection 인터페이스에서 상속된다는 점을 제외하면 질문에 구체적으로 대답할 수 없습니다.일반 컬렉션 중 어느 것도 이를 사용하지 않으며 ICollection<T> 인터페이스는 SyncRoot를 포함하지 않습니다.

포함되지 않은 이유에 대해서는 라이브러리 디자이너가 의도한 방식으로 사용되지 않았거나 단순히 최신 컬렉션에 유지하는 것을 정당화할 만큼 충분히 사용되지 않았다고 추측할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top