1

いくつかの異なるタスクを送信するExecutors.newFixedThreadPool(1)があり(すべてRunnableを実装しています)、それらはキューに入れられ、順番に正しく実行されますか?各タスクの1つだけを一度に実行またはキューに入れることを許可する最良の方法は何ですか?すでにキューにあるExecutorServiceに送信されたすべてのタスクを無視したいと思います。

4

2 に答える 2

1

いくつかの異なるタスクを送信する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)をクラスに含めると言います。

于 2010-04-08T03:21:43.907 に答える
0

スレッドプールは、タスクの順序を保証するものではありません。

ThreadPoolExecutor.DiscardPolicy2番目の部分については、を使用して、拒否された実行ハンドラーを設定できます。ThreadPoolExecutor

于 2010-04-08T01:05:35.913 に答える