Java 5 なので、まよわず ThreadPoolExecutor を利用することに。
んで、ハマった挙動についてメモ。
ThreadPoolExecutor はシンプルな FIFO (LIFO) を提供してくれるものと
思っていたが、実はそうではない。ハマりどころはcorePoolSizeとmaximumPoolSizeの設定値と指定する Queue のサイズによっては
シンプルな FIFO(LIFO) にはならないということ。
Javadoc からすると、
- corePoolSize
- 通常使う thread の数。
- maximumPoolSize
- thread の最大数
とある。なので、
corePoolSize = 3
maximumPoolSize = 5
とかで Executor を作ったら、通常は 3 つ。Queue があふれてきたら、最大 5 つで動作するという認識だった。
この認識は正解で、最初は thread 3 つで稼働。thread 3 つが埋まると、キューイングされていき、最大キューイング数に達すると thread が増えていった。
が、thread が増えた際に処理されるキューが FIFO ではなかった。
何が処理されたかというと、キューイングであふれた新着 JOB だった。
挙動をまとめると、
- job 到着時、通常 thread が開いていたら即座に thread 生成。
- 通常 thread が埋まっている場合、キューイング
- 通常 thread が埋まっているかつ、キューイングも埋まっている場合、新着 Job を 新規 thread 生成で実行。
- MAX thread まで埋まるかつ、キューイングが一杯の場合、execute 時にエラーを吐く。
- 新着 Job がこなくて、thread が空くと、キューの先頭 Job が処理される。
FIFO ではないでしょ?
Java 屋なんだけど、初めて Java の記事をのっけた気がする。。。
以上。