いくつかの異なるタスクを送信するExecutors.newFixedThreadPool(1)があり(すべてRunnableを実装しています)、それらはキューに入れられ、順番に正しく実行されますか?各タスクの1つだけを一度に実行またはキューに入れることを許可する最良の方法は何ですか?すでにキューにあるExecutorServiceに送信されたすべてのタスクを無視したいと思います。
2 に答える
いくつかの異なるタスクを送信するExecutors.newFixedThreadPool(1)があり(すべてRunnableを実装しています)、それらはキューに入れられ、順番に正しく実行されますか?
はい、デフォルトでは、基盤となるスレッドプールエグゼキュータはLinkedBlockingQueueで作成されます。ワーカースレッドは1つだけで、キューはFIFO方式で使用されるため、タスクは順番に実行されます。
各タスクの1つだけを一度に実行またはキューに入れることを許可する最良の方法は何ですか?すでにキューにあるExecutorServiceに送信されたすべてのタスクを無視したいと思います。
私が考える最も簡単な方法は、ThreadPoolExecutorを拡張する独自のExecutorServiceを作成することです。次に、execute()メソッドをオーバーライドして、スーパークラスexecuteに委任する前にBlockingQueue#contains(Object)を呼び出すようにします。
public class LimitedExecutorService extends ThreadPoolExecutor {
public LimitedExecutorService(final int nThreads) {
super(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
@Override
public void execute(Runnable command) {
if (!this.getQueue().contains(command)) {
super.execute(command);
} else {
//reject
}
}
}
注:多くの人は、ThreadPoolExecutorを拡張するべきではないと主張しますが、代わりに、ExecutorServiceを実装し、委任先のThreadPoolExecutor(別名composition)をクラスに含めると言います。
スレッドプールは、タスクの順序を保証するものではありません。
ThreadPoolExecutor.DiscardPolicy
2番目の部分については、を使用して、拒否された実行ハンドラーを設定できます。ThreadPoolExecutor