Подтвердить что ты не робот

Какова возможная причина для java.util.concurrent.RejectedExecutionException в SingleThreadExecutor

Я создаю следующий исполнитель в singleton:

   final private ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
        final ThreadFactory delegate = Executors.defaultThreadFactory();
        public Thread newThread(Runnable paramAnonymousRunnable) { 
            Thread localThread =      this.delegate.newThread(paramAnonymousRunnable);
            localThread.setName("MyTask-" + localThread.getName());
            localThread.setDaemon(XXX.this.daemonThread);
            return localThread;
        }
    });

И во время выполнения программы есть много вызовов этому методу синглтона. Вызовы выполняются в разных потоках и, возможно, в одно время.

private void send(final String paramString) {
  try {
      this.executor.execute(new Runnable() {
          public void run() {
              //DO some interesting stuff
          }
      });
  } catch (Exception localException) {
    this.handler.handle(localException);
  }

}

И в какой-то момент начинают появляться следующие стеки:

java.util.concurrent.RejectedExecutionException
        at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1774)
        at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768)
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656)
        at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:589)
        at XXXXX.send(XXXX.java:269)

Почему jvm выдает такое исключение?

SingleThreadExecutor поддерживается ссылкой LinkedBlockingQueue().
И пул потоков не был выключен.

для информации, jvm is oracle jdk 1.6. Синглтон создан с помощью spring. копия из java.util.concurrent.Executors:

   public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>(),
                                threadFactory));
   }
4b9b3361

Ответ 1

Есть две причины, по которым execute выбрасывает RejectedExecutionException

  • Очередь заполнена, и вы не можете добавить больше потоков
  • Завершение работы ThreadPool

Поскольку вы используете LinkedBlockingQueue, единственный способ увидеть это происходит потому, что вы завершаете пул.

Ответ 2

Возможно, вы отправили задачи после вызова executor.shutdown(). Обычно для остановки исполнителя они выполняют

    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);

Ответ 3

Возможно, вы должны использовать пул потоков вместо одного исполнителя.

    executor = new java.util.concurrent.ThreadPoolExecutor(30, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory() {
        final AtomicInteger threadNumber = new AtomicInteger( 1 );
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "Thread No : " + threadNumber.getAndIncrement());
        }
    });