it-swarm.com.de

Was ist der mögliche Grund für eine Java.util.concurrent.RejectedExecutionException in einem SingleThreadExecutor

Ich erstelle den folgenden Executor in einem 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;
        }
    });

Und während der Ausführung des Programms wird diese Methode des Singleton viel aufgerufen. Die Aufrufe erfolgen in verschiedenen Threads und möglicherweise zur gleichen Zeit.

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);
  }

}

Und irgendwann erscheinen die folgenden Stapel:

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)

Warum wird der jvm eine solche Ausnahme auslösen?

Der singleThreadExecutor wird von einem LinkedBlockingQueue () gesichert.
Und der Threadpool wurde nicht heruntergefahren.

zur Information ist der jvm Oracle jdk 1.6. Das Singleton wird mit spring . Copy von Java.util.concurrent.Executors erstellt:

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

Es gibt zwei Gründe, warum execute eine RejectedExecutionException werfen würde. 

  1. Die Warteschlange ist voll und Sie können keine weiteren Threads hinzufügen
  2. Der ThreadPool wurde heruntergefahren

Da Sie eine LinkedBlockingQueue verwenden, kann ich das nur so sehen, weil Sie den Pool herunterfahren.

54
John Vint

Möglicherweise haben Sie nach dem Aufruf von executor.shutdown() Aufgaben übermittelt. Normalerweise stoppen sie den Executor

    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);
4
Andrey Chaschev

Für die Ausführung der angegebenen Aufgabe stehen keine Threads zur Verfügung. Keine verknüpfte Blockwarteschlange an Warteschlange.

Vielleicht sollten Sie einen Thread-Pool verwenden, anstatt einen einzelnen Executor zu verwenden. 

    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());
        }
    });
0
cgon