web-dev-qa-db-fra.com

Comment interrompre les threads d'ExecutorService

Lorsque j'utilise le ExecutorService renvoyé par Executors.newSingleThreadExecutor(), comment puis-je l'interrompre?

32
Ofek Ron

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.

37
erickson

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.

6
Priidu Neemre

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.

0
wtsolid