ThreadPoolExecutor を使用してタスクをスケジュールしようとしていますが、そのポリシーで問題が発生しています。その動作は次のとおりです。
- 実行中のスレッドが corePoolSize よりも少ない場合、Executor は常に、キューに入れるよりも新しいスレッドを追加することを優先します。
- corePoolSize 以上のスレッドが実行されている場合、Executor は常に、新しいスレッドを追加するよりも要求をキューに入れることを優先します。
- 要求をキューに入れることができない場合、これが maximumPoolSize を超えない限り、新しいスレッドが作成されます。この場合、タスクは拒否されます。
私が望む動作はこれです:
- 同上
- corePoolSize より多いが maximumPoolSize より少ないスレッドが実行されている場合、キューイングよりも新しいスレッドの追加を優先し、新しいスレッドの追加よりもアイドル スレッドの使用を優先します。
- 同上
基本的に、どのタスクも拒否されたくありません。それらを無制限のキューに入れたい。しかし、私は maximumPoolSize スレッドまで持ちたいと思っています。無制限のキューを使用すると、coreSize に達するとスレッドが生成されません。バインドされたキューを使用すると、タスクが拒否されます。これを回避する方法はありますか?
私が今考えているのは、SynchronousQueue で ThreadPoolExecutor を実行することですが、タスクを直接フィードするのではなく、別の無制限の LinkedBlockingQueue にフィードすることです。次に、別のスレッドが LinkedBlockingQueue から Executor にフィードし、拒否された場合は、拒否されなくなるまで再試行します。これは面倒でちょっとしたハックのように思えますが、これを行うためのよりクリーンな方法はありますか?