Je crée l'exécuteur suivant dans un 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;
}
});
Et lors de l'exécution du programme, il y a beaucoup d'appels à cette méthode du singleton. Les appels sont effectués dans différents threads et peut-être à la même heure.
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);
}
}
Et à un moment donné, les piles suivantes commencent à apparaître:
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)
Pourquoi le JVM lancera une telle exception?
SingleThreadExecutor est soutenu par un LinkedBlockingQueue ().
Et le pool de threads n'a pas été arrêté.
pour information, le jvm est Oracle jdk 1.6. Le singleton est créé avec spring ..__ copy à partir de Java.util.concurrent.Executors:
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
Il y a deux raisons pour lesquelles execute
jette un RejectedExecutionException
Puisque vous utilisez une LinkedBlockingQueue
, la seule manière pour que cela se produise est d’arrêter le pool.
Vous avez peut-être soumis des tâches après avoir appelé executor.shutdown()
. Normalement pour arrêter l'exécuteur qu'ils font
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
Les threads ne sont pas disponibles pour exécuter la tâche donnée. Aucune file d'attente bloquée liée à la tâche que.
Peut-être devriez-vous utiliser un pool de threads au lieu d'utiliser un seul exécutant.
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());
}
});