2

にバインドされたキューを使用しThreadPoolExecutorたいのですが、カスタムを使用したいですRejectedExecutionExceptionHandler。拒否されたタスクを別のキューに入れ、しばらくしてから再送信しようとするために、そうする必要があります。
カスタムRejectedExecutionExceptionHandlerは私の問題の解決策ですか? はいの場合、どのように実装しますか?
または、私の問題に対処する最善の方法は何ですか?

4

2 に答える 2

2

あなたの場合、境界付きキューがいっぱいになったときにのみ機能する飽和ポリシーを選択する必要があります。スレッド プール エグゼキューターの飽和ポリシーは、メソッドを呼び出すことで変更できますsetRejectedExecutionHandler()。飽和ポリシーには 4 つのタイプがあります。

  1. 中止 (これは実際に例外をスローし、呼び出し元に処理させます)
  2. 破棄 (これにより、新しく送信されたタスクが実際に破棄されます)
  3. 破棄 - 最も古い (これにより、次に実行される予定だったタスクが破棄され、新しいタスクの再送信が試行されます)
  4. タスクを破棄したり、例外をスローしたりせず、代わりに作業の一部を呼び出し元に戻すことで、新しいタスクのフローを遅くしようとするなんらかの形式のスロットリングを実装する呼び出し元実行ポリシー。そのため、呼び出し元のスレッドは新しいタスクの実行でビジー状態になり、その間はそれ以上のタスクを受け入れることができなくなります。

CallerRunsPolicy()あなたの状況では、私は最も理にかなっていると思います。これを行う :

executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
于 2012-08-07T09:05:59.667 に答える
1

後で使用するために実行できないタスクをキューに入れるため、無制限のキューを使用します。あなたの場合、 Executors.newFixedThreadPool を訴えます。あなたはこれが何をするかに興味があるかもしれません

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

注: 無制限のキューを使用します。

問題に対処する最も簡単で最良の方法は、現在のスレッドでタスクを実行することです。

これにより、予備のバックグラウンド スレッドがない現在のスレッドを使用して、すべてのタスクがタイムリーに実行されるようになります。

new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        r.run();
    }
}
于 2012-08-06T08:59:21.930 に答える