Lorsque j'utilise le ExecutorService
renvoyé par Executors.newSingleThreadExecutor()
, comment puis-je l'interrompre?
Pour ce faire, vous devez submit()
une tâche vers un ExecutorService
, plutôt que d'appeler execute()
. Lorsque vous effectuez cette opération, un Future
est renvoyé qui peut être utilisé pour manipuler la tâche planifiée. En particulier, vous pouvez appeler cancel(true)
sur le Future
associé pour interrompre une tâche en cours d'exécution (ou ignorer complètement l'exécution si la tâche n'a pas commencé à s'exécuter). encore).
Soit dit en passant, l'objet renvoyé par Executors.newSingleThreadExecutor()
est en fait un ExecutorService
.
Une autre façon d'interrompre les threads gérés en interne par l'exécuteur consiste à appeler la méthode shutdownNow(..)
sur votre ExecutorService
. Notez, cependant, que contrairement à la solution de @ erickson, cela rendra l'ensemble ThreadPoolExecutor
inapte à une utilisation ultérieure.
Je trouve cette approche particulièrement utile dans les cas où le ExecutorService
n'est plus nécessaire et où garder un œil sur les instances de Future
est par ailleurs inutile (un excellent exemple de ceci étant la exit(..)
méthode d'application).
Informations pertinentes provenant des javadocs ExecutorService#shutdownNow(..)
:
Tente d'arrêter toutes les tâches en cours d'exécution, arrête le traitement des tâches en attente et renvoie une liste des tâches en attente d'exécution.
Il n'y a aucune garantie au-delà des tentatives d'effort pour arrêter le traitement des tâches en cours d'exécution. Par exemple, les implémentations typiques seront annulées via Thread.interrupt, de sorte que toute tâche qui ne répond pas aux interruptions peut ne jamais se terminer.
Une façon appropriée pourrait être de personnaliser/injecter ThreadFactory pour le service d'exécution et à partir de la fabrique de threads, vous avez créé le descripteur du thread, puis vous pouvez planifier une tâche pour interrompre le thread intéressé.
Partie de code de démonstration pour la méthode remplacée "newThread" dans ThreadFactory:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
},
5,
TimeUnit.SECONDS);
return thread;
}
}
Ensuite, vous pouvez utiliser ci-dessous pour construire votre instance de service d'exécution:
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
Ensuite, après 5 secondes, un signal d'interruption sera envoyé aux threads du service d'exécution.