http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
1. Direct handoffs (e.g. SynchronousQueue)
Work Queue에 가장 이상적인 형태로, 태스크를 멈추지(lock) 않고 기존 스레드나 새
스레드에서 수행하는 것이다.
태스크끼리 의존성이 있을 경우 유용하다.
태스크를 모두 수행해야 하므로, 제한없는(unbounded) maximumPoolSize가
필요하다.
하지만 스레드 수가 매우 빠르게 증가할 수 있다.
2. Unbounded queues (e.g.
LinkedBlockingQueue without predefined capacity)
corePoolSize만큼의 모든 스레드가 바쁠 때, 태스크를 기다리게 한다.
새 스레드를 생성하지 않으므로 maximumPoolSize도 의미 없다.
웹서버처럼 각 태스크가 독립적인 경우 유용하다.
돌발적으로 갑자기 태스크가 급증하는 경우에 부드럽게 처리할 수 있는 장점이 있다.
하지만 큐에 대기하는 태스크가 매우 빠르게 증가할 수 있다.
* ThreadPoolExecutor는 사용하는 BlockingQueue를 생성할 때,
인자를 주지 않고 capacity를 정하지 않으므로 Unbounded queue처럼 동작한다.
3. Bounded queues (e.g.
ArrayBlockingQueue)
CPU, OS, Context-Switching등의 리소스 소진(exhaustion)을 막는데
유용하다.
하지만 튜닝하기가 어렵다. 왜냐하면 큐 크기와 스레드풀 크기는 상호관계(trade off)가 있기
때문이다.
예를 들어, 큰 큐와 작은 풀을 사용할 경우, 리소스의 사용은 최소화할 수 있지만,
처리량(throuput)이 매우 작아진다.
예를 들어, 작은 큐와 큰 풀을 사용할 경우, CPU는 최대한 사용할 수 있지만, 많은 스레드에
의한 스케쥴링 오버헤드로 오히려 throuput 이 저하될 수 있다.
'네트워크 프로그래밍 > Java NIO' 카테고리의 다른 글
[박혜웅] java.util.concurrent.ThreadPoolExecutor (2) | 2011.10.31 |
---|---|
[박혜웅] java.util.concurrent.Executors (0) | 2011.10.31 |