Comment arrêter/tuer un thread Java de longue durée lors de l'exécution ? temporisé -> annulé -> états interrompus
Publié: 2021-07-17Vous êtes-vous déjà demandé comment tuer un thread Java de longue durée ? Avez-vous l'une des questions ci-dessous ?
- Tuer/Arrêter un fil après un certain laps de temps
- Tuer le thread après un certain délai spécifié en Java
- Comment tuer un thread Java
- Comment arrêter un thread en Java avec un exemple
- comment arrêter le thread dans l'exemple de code java
- comment arrêter un thread en java sans utiliser la méthode d'arrêt
Si vous avez l'une des questions ci-dessous, vous êtes au bon endroit. Aujourd'hui, nous allons passer en revue un exemple simple qui montre comment Java8 supprime les threads de longue durée.
Qu'est-ce qu'une logique :
- Créer la classe CrunchifyJavaTaskTimeout.java
- Créez un exécuteur de thread Java avec une seule taille de pool de threads.
- Créer 4 futures tâches d'un objet
CrunchifyRunner
avec un délai de 3 secondes - CrunchifyRunner.java est une classe simple qui implémente la méthode
call()
- Il introduit un délai de
20 seconds
sifutureTask = 4
- Il introduit un délai de
- Une fois que le futur atteint
3 seconds
, il crée une exception de délai d'attente si le thread est toujours en cours d'exécution- Une fois le délai expiré, nous devons annuler la tâche à l'aide de crunchifyFuture.
cancel( true )
; - Une fois que futureTask est annulé, il déclenchera
InterruptedException
(lancé lorsqu'un thread est en attente, en sommeil ou autrement occupé, et que le thread est interrompu, avant ou pendant l'activité. Parfois, une méthode peut souhaiter tester si le thread actuel a été interrompu, et si c'est le cas, lever immédiatement cette exception.)
- Une fois le délai expiré, nous devons annuler la tâche à l'aide de crunchifyFuture.
Commençons:
Étape 1 Créer la classe CrunchifyRunner.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
package crunchify . java . tutorials ; import java . text . SimpleDateFormat ; import java . util . Date ; import java . util . concurrent . Callable ; /** * @author Crunchify.com * Version: 1.0.1 * */ public class CrunchifyRunner implements Callable < Boolean > { private int workerNumber ; public int getNumber ( ) { return workerNumber ; } public void setNumber ( int workerNumber ) { this . workerNumber = workerNumber ; } public CrunchifyRunner ( int workerNumber ) { this . workerNumber = workerNumber ; setNumber ( workerNumber ) ; } SimpleDateFormat crunchifyFormatter = new SimpleDateFormat ( "dd-MMMMM-yyyy hh:mm:ss" ) ; public Boolean call ( ) throws InterruptedException { try { if ( workerNumber == 4 ) { // Sleep for 20 Seconds to generate long running thread. Thread . sleep ( 20000 ) ; } else { Thread . sleep ( 50 ) ; } } catch ( InterruptedException ie ) { log ( "\n" + crunchifyFormatter . format ( new Date ( ) ) + " crunchifyWorker task " + workerNumber + " interrupted." ) ; log ( "\n=======> Basically once thread is timed out, it should be cancelled and interrupted. (timedout ==> cancelled ==> interrupted)" ) ; } // Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a // method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception. return true ; } public void log ( String info ) { System . out . println ( info ) ; } } |
Étape 2 Créez la classe CrunchifyJavaTaskTimeout.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
package crunchify . java . tutorials ; import java . text . SimpleDateFormat ; import java . util . ArrayList ; import java . util . Collection ; import java . util . Date ; import java . util . List ; import java . util . concurrent . Callable ; import java . util . concurrent . CompletionService ; import java . util . concurrent . ExecutionException ; import java . util . concurrent . ExecutorCompletionService ; import java . util . concurrent . Executors ; import java . util . concurrent . Future ; import java . util . concurrent . TimeUnit ; /** * @author Crunchify.com * Version: 1.0.2 * */ public class CrunchifyJavaTaskTimeout { @ SuppressWarnings ( { "rawtypes" , "unchecked" } ) public static void main ( final String [ ] args ) { // Creates an ExecutorCompletionService using the supplied executor for base task execution and a LinkedBlockingQueue as a completion queue. CompletionService < Boolean > crunchifyService = new ExecutorCompletionService < Boolean > ( Executors . newFixedThreadPool ( 1 ) ) ; Collection < CrunchifyRunner > crunchifyThreads = new ArrayList < CrunchifyRunner > ( 50 ) ; crunchifyThreads . add ( new CrunchifyRunner ( 1 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 2 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 3 ) ) ; crunchifyThreads . add ( new CrunchifyRunner ( 4 ) ) ; SimpleDateFormat crunchifyFormatter = new SimpleDateFormat ( "dd-MMMMM-yyyy hh:mm:ss" ) ; List < Future < Boolean > > crunchifyFutures = new ArrayList < Future < Boolean > > ( crunchifyThreads . size ( ) ) ; try { // Let's first add all tasks to future for ( Callable crunchifyTask : crunchifyThreads ) { crunchifyFutures . add ( crunchifyService . submit ( crunchifyTask ) ) ; } for ( int count = 1 ; count < = crunchifyFutures . size ( ) ; count ++ ) { // Let's put Future timeout to 3 Seconds Future < Boolean > crunchifyResult = crunchifyService . poll ( 3000 , TimeUnit . MILLISECONDS ) ; if ( crunchifyResult == null ) { log ( crunchifyFormatter . format ( new Date ( ) ) + "\n ==> crunchifyWorker task " + count + " timedout." ) ; // So lets cancel the first futures we find that haven't completed for ( Future crunchifyFuture : crunchifyFutures ) { if ( crunchifyFuture . isDone ( ) ) { continue ; } else { crunchifyFuture . cancel ( true ) ; log ( " ==> crunchifyWorker task " + count + " cancelled." ) ; break ; } } continue ; } else { try { if ( crunchifyResult . isDone ( ) && !crunchifyResult.isCancelled() && crunchifyResult.get()) { log(crunchifyFormatter.format(new Date()) + " ==> crunchifyWorker task " + count + " completed."); } else { log ( crunchifyFormatter . format ( new Date ( ) ) + " ==> crunchifyWorker task failed" ) ; } } catch ( ExecutionException exception ) { log ( exception . getMessage ( ) ) ; } } } } catch ( InterruptedException exception ) { // Log exception message log ( exception . getMessage ( ) ) ; } finally { // Cancel by interrupting any existing tasks currently running in Executor Service for ( Future < Boolean > future : crunchifyFutures ) { future . cancel ( true ) ; } } log ( "\n=======> All tasks completed. Now long running thread 4 should be interrupted immediately after this." ) ; System . exit ( 0 ) ; } private static void log ( String string ) { System . out . println ( string ) ; } } |

Étape 3
Faites un clic droit sur CrunchifyJavaTaskTimeout.java et exécutez-le en tant qu'application Java.
Vous verrez ci-dessous le résultat dans la console Eclipse.
1 2 3 4 5 6 7 8 9 10 11 12 |
27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 1 completed . 27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 2 completed . 27 - November - 2018 10 : 32 : 29 == > crunchifyWorker task 3 completed . 27 - November - 2018 10 : 32 : 32 == > crunchifyWorker task 4 timedout . == > crunchifyWorker task 4 cancelled . ======= > All tasks completed . Now long running thread 4 should be interrupted immediately after this . 27 - November - 2018 10 : 32 : 32 crunchifyWorker task 4 interrupted . ======= > Basically once thread is timed out , it should be cancelled and interrupted . ( timedout == > cancelled == > interrupted ) |
Faites-moi savoir si vous avez des questions sur ce sujet.