web-dev-qa-db-ja.com

ThreadPoolExecutorから拒否された将来のタスク

ThreadPoolExecutorがあり、それにタスクを送信します。

private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));

このコードは、RunnableThreadPoolExecutorに送信します。

 protected void waitAndSweep(final String symbol) {

    runnable = new Runnable() {
      public void run() { /* irrelevant code */ }
    };

    try {
      Future<?> self = threadPoolExecutor.submit(runnable);
      futures.add(self);
    } catch (RejectedExecutionException re) {
      /* this exception will be thrown when wait and sweep is called more than twice.
       * threadPoolExecutor can have one running task and one waiting task.
       */
    } catch (Exception e) {
      logEvent(StrategyEntry.ERROR, "waitAndSweep", symbol, "Exception caught...", e);
    }
  }

次のコードはタスクを停止します。

protected synchronized void stop(StrategyEntry entry) throws Exception {
    for (Object future : futures) {
      ((Future<?>) future).cancel(true);
    }
    futures.clear();

    threadPoolExecutor.shutdown();
}

ここでの問題は次のとおりです。タスクを停止しようとすると、次の例外が発生します。

タスクJava.util.concurrent.FutureTask@3a475611がJava.util.concurrent.ThreadPoolExecutor@216393fbから拒否されました[終了、プールサイズ= 0、アクティブスレッド= 0、キューに入れられたタスク= 0、完了したタスク= 1]

7
MMPgm

問題は、stopメソッドでexcutorをshutdown()することです。タスクが完了するのを待つだけの場合は、Future.get()を使用します。エグゼキュータがシャットダウンされると、タスクをエグゼキュータに送信できなくなります。

shutdown()は、実際にアプリケーションを終了する場合にのみ使用してください。

8
RAnders00