본문으로 건너뛰기
김신건의 로그

[Java] SynchronousQueue

· 수정 · 📖 약 1분 · 216자/단어 #java #concurrent #queue #blocking #handoff
SynchronousQueue, java.util.concurrent.SynchronousQueue, 직접 핸드오프 큐

정의

java.util.concurrent.SynchronousQueue<E>용량 0 의 BlockingQueue. 저장 공간이 없다. put 은 매칭되는 take 가 있어야 진행하고, 반대도 마찬가지.

직접 핸드오프 (direct handoff) 패턴, producer 와 consumer 가 서로를 정확히 한 명씩 기다린다.

시각화

특수한 동작

SynchronousQueue<String> q = new SynchronousQueue<>();
q.size();           // 항상 0
q.isEmpty();        // 항상 true
q.peek();           // 항상 null
q.iterator().hasNext();   // 항상 false

q.put("x");         // take 자가 없으면 block
q.take();           // put 자가 없으면 block

q.offer("x");       // take 자가 즉시 없으면 false 반환
q.poll();           // put 자가 즉시 없으면 null 반환

사용 사례

Executors.newCachedThreadPool() 의 내부 큐

ExecutorService pool = Executors.newCachedThreadPool();

내부적으로 SynchronousQueue 를 사용. 새 작업이 오면 idle thread 가 있으면 즉시 전달, 없으면 새 thread 생성. 큐에 작업이 쌓이지 않는다.

Producer 가 Consumer 도착을 보장받아야 할 때

SynchronousQueue<Order> q = new SynchronousQueue<>();

// Producer
q.put(order);   // consumer 가 이 order 를 받는 것을 확인하고 진행

// Consumer
Order o = q.take();
process(o);

저장 공간이 없으므로 producer 입장에서 “내 데이터가 처리됐다” 는 시점이 명확. 다만 throughput 은 producer/consumer 가 항상 비슷한 속도여야만 좋다.

공정성 옵션

SynchronousQueue<String> fair = new SynchronousQueue<>(true);   // FIFO
SynchronousQueue<String> unfair = new SynchronousQueue<>();      // LIFO 기본

true 면 가장 오래 기다린 스레드부터 매칭.

참고

이 글의 용어 (3개)
[Java] BlockingQueuejava
정의 는 요소를 가져올 때 비어 있으면 대기, 넣을 때 가득 차 있으면 대기 하는 thread-safe 큐 인터페이스. 생산자-소비자 (producer-consumer) 패턴의 …
[Java] LinkedBlockingQueuejava
정의 는 linked list 기반의 . 기본 unbounded ( ) 이지만 생성 시 capacity 지정 가능. Two-Lock Queue 알고리즘 으로 producer 와 …
Blocking (블로킹)concurrency
정의 Blocking 은 호출이 결과가 준비될 때까지 호출 스레드를 멈춰두는 실행 방식. 멈춰 있는 동안 그 스레드는 다른 일을 할 수 없다. OS 가 스레드를 sleep 상태로…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기