문제

내 질문은 다음과 관련이 있습니다. 이 질문 아까 물었다.생산자와 소비자 스레드 간의 통신을 위해 대기열을 사용하는 상황에서 사람들은 일반적으로 다음을 사용하는 것을 권장합니다. LinkedBlockingQueue 또는 ConcurrentLinkedQueue?

다른 것보다 하나를 사용하는 것의 장점/단점은 무엇입니까?

API 관점에서 볼 수 있는 주요 차이점은 LinkedBlockingQueue 선택적으로 제한될 수 있습니다.

도움이 되었습니까?

해결책

생산자/소비자 스레드의 경우 확실하지 않습니다. ConcurrentLinkedQueue 합리적인 옵션이기도합니다. 구현되지 않습니다 BlockingQueue, 이것은 생산자/소비자 대기열 IMO의 기본 인터페이스입니다. 당신은 전화해야합니다 poll(), 당신이 아무것도 찾지 못했다면 조금 기다렸다가 다시 설문 조사 등 ... 새로운 아이템이 들어 오면 지연이 발생하고 비어있을 때 비효율적으로 (수면에서 불필요하게 깨어나기 때문에) 비효율적입니다.

Blockingqueue의 문서에서 :

BlockingQueue 구현은 주로 생산자 소비자 대기열에 사용되도록 설계되었습니다.

나는 그것이 그렇지 않다는 것을 안다 엄격하게 차단 대기열 만 생산자 소비자 대기열에 사용해야한다고 말하지만 ...

다른 팁

이 질문에는 더 나은 답변이 필요합니다.

자바의 ConcurrentLinkedQueue 유명한 것을 기반으로합니다. Maged M의 알고리즘마이클과 마이클 L.스캇 ~을 위한 비차단 잠금 없음 대기열.

여기서 경합 리소스(큐)에 대한 용어인 "비차단"은 스레드 중단과 같이 플랫폼의 스케줄러가 수행하는 작업에 관계없이 또는 문제의 스레드가 너무 느린 경우 다른 스레드가 동일한 리소스에 대해 경합하는 것을 의미합니다. 여전히 발전할 수 있을 것입니다.예를 들어 잠금이 포함된 경우 잠금을 보유하는 스레드가 중단될 수 있으며 해당 잠금을 기다리는 모든 스레드가 차단됩니다.내장 잠금( synchronized 키워드)는 Java에서 성능에 심각한 불이익을 가져올 수도 있습니다. 편향된 잠금 관련되어 있고 경합이 있거나 VM이 스핀 유예 기간 후 잠금을 "팽창"하고 경합 스레드를 차단하기로 결정한 후...그렇기 때문에 많은 컨텍스트(낮거나 중간 경합 시나리오)에서 원자 참조에 대한 비교 및 ​​설정을 수행하는 것이 훨씬 더 효율적일 수 있으며 이것이 바로 많은 비차단 데이터 구조가 수행하는 작업입니다.

자바의 ConcurrentLinkedQueue 비차단 기능일 뿐만 아니라 생산자가 소비자와 다투지 않는다는 놀라운 특성을 가지고 있습니다.단일 생산자/단일 소비자 시나리오(SPSC)에서 이는 사실상 경합이 없음을 의미합니다.다중 생산자/단일 소비자 시나리오에서 소비자는 생산자와 경합하지 않습니다.여러 생산자가 시도할 때 이 대기열에는 경합이 있습니다. offer(), 그러나 이는 정의상 동시성입니다.기본적으로 범용적이고 효율적인 비차단 대기열입니다.

그것이 아닌 것에 관해서는 BlockingQueue, 글쎄요, 큐에서 대기하도록 스레드를 차단하는 것은 동시 시스템을 설계하는 데 있어서 엄청나게 끔찍한 방법입니다.하지 않다.사용법을 알 수 없다면 ConcurrentLinkedQueue 소비자/생산자 시나리오에서는 좋은 행위자 프레임워크와 같은 더 높은 수준의 추상화로 전환하면 됩니다.

LinkedBlockingQueue 대기열이 비어 있거나 가득 차면 소비자 또는 생산자를 차단하고 각 소비자/생산자 스레드가 잠들게됩니다. 그러나이 차단 기능은 비용과 함께 제공됩니다. 모든 풋 또는 테이크 작업에는 생산자 또는 소비자 (많은 경우)가 제작되는 모든 운영이 제적으로 발생하므로 많은 생산자/소비자가있는 시나리오에서는 운영이 느려질 수 있습니다.

ConcurrentLinkedQueue 자물쇠를 사용하지 않고 있습니다 카스, Put/Take 운영에서 많은 생산자 및 소비자 스레드와의 경합을 줄일 수 있습니다. 그러나 "무료"데이터 구조이기 때문에 ConcurrentLinkedQueue 비어있을 때 차단하지 않으므로 소비자가 take() 반환 null 예를 들어 소비자 스레드가 CPU를 섭취하면서 "바쁜 대기"에 의한 값.

따라서 "더 나은"것은 소비자 실의 수, 소비/생산 속도 등에 따라 다릅니다. 각 시나리오에 벤치 마크가 필요합니다.

하나의 특정 사용 사례 ConcurrentLinkedQueue 생산자가 처음으로 무언가를 생산하고 일을 대기열에 배치하여 작업을 마치는 경우가 분명합니다. 그리고 후에 만 소비자는 큐가 비어있을 때 수행 될 것이라는 것을 알면서 소비하기 시작합니다. (여기서는 생산자 소비자 사이의 동시성이 아니라 생산자 프로듀서와 소비자 소비자 사이에만 동시성이 있습니다)

다른 솔루션 (잘 확장되지 않은)

큐가 확장 할 수없고 생산자/소비자 스레드가 하나만 포함 된 경우. Lockless 큐를 사용할 수 있습니다 (데이터 액세스를 잠글 필요가 없습니다).

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