Les pools de threads peuvent exécuter plusieurs tâches simultanément. Parfois, nous pouvons vouloir suivre les résultats d'exécution des tâches. Même dans un certain délai, si la tâche n'est pas terminée, nous pouvons également vouloir annuler l'exécution des tâches. Afin de prendre en charge cette fonctionnalité, ThreadPoolExecutor fournit FutureTask pour suivre l'exécution et l'annulation des tâches. Cet article présente le principe de mise en œuvre de FutureTask.
Afin de mieux comprendre le principe de mise en œuvre de Futuretask, nous fournissons d'abord plusieurs interfaces et structures de classe importantes, comme le montre la figure ci-dessous:
ThreadPoolExecutor fournit l'interface de soumission pour la soumission de tâches. Soumettre prend en charge deux interfaces différentes: Runnable et appelant. Afin de fournir une interface externe unifiée, JDK s'envalie en interne dans un appelable, qui est tous implémenté via l'adaptateur RunnableAdapter. Ce qui suit est le code source de runnableAdapter:
classe finale statique runnableAdapter <T> implémente callable <T> {tâche finale Runnable; Résultat final final; RunnableAdapter (runnable task, t result) {this.task = tâche; this.result = result; } public t Call () {task.run (); Résultat de retour; }}RunNableAdapter est la classe d'implémentation de Calable, qui implémente la méthode d'appel. La méthode d'appel appelle simplement Task.Run () puis renvoie le résultat, ce qui garantit que seule l'interface appelée doit être gérée uniformément en interne.
Grâce à la section précédente, nous savons que la tâche exécutable soumise est convertie en interne en tâches appelables. Vérifiez la valeur de retour de la méthode de soumission, qui est un avenir. En fait, cet avenir est une instance FutureTask. Grâce à cette instance, l'appel de la méthode GET peut bloquer le thread actuel jusqu'à la fin de la tâche et le résultat est renvoyé.
Toute la chaîne d'appels ressemble à ceci:
Thread de travailleur -> futureTask.run () -> callable.call () -> task.run ()
Si la tâche appelable est soumise, il n'y a que les trois premiers appels.
Afin de mieux démontrer l'ensemble du processus, les exemples suivants seront utilisés pour démontrer le processus d'exécution.
1. Soumettez une tâche appelable au pool de threads (Runnable sera également converti en appelant). À l'heure actuelle, le callable est transmis dans une instance Futuretask, comme indiqué ci-dessous:
2. Le pool de thread utilise un thread pour exécuter la tâche Futuretask.
Le processus d'exécution des tâches est relativement simple. En fin de compte, la méthode callable.call () ou runnable.run () sera appelée, et un résultat sera obtenu, ce qui stockera le résultat dans la propriété Résultat de l'instance FutureTask, et l'état sera modifié à la normale, indiquant que la tâche a été exécutée et le résultat peut être obtenu.
Nous supposons que plusieurs threads appellent la méthode GET de la même instance FutureTask lors de l'exécution de callable.call() . À l'heure actuelle, ces fils seront bloqués et stockés dans une pile, comme le montre la figure ci-dessous:
Les threads 1, 2 et 3 appellent FutureTask.get . Étant donné que la tâche n'a pas été exécutée, les trois threads seront bloqués et somnoleurs. Il y a une pile dans FutureTask pour stocker les fils d'attente. Le pointeur supérieur de la pile est référencé par FutureTask.waiters . Lorsque la tâche est exécutée, les threads de toute la pile iténeront. À l'heure actuelle, chaque thread sera éveillé et le résultat de l'exécution de la tâche peut être obtenu avec succès (le résultat de l'exécution est stocké dans FutureTask.outcome) .
FutureTask prend également en charge la fonction d'annulation des tâches, qui coordonnent tous plusieurs threads via l'état de FutureTask.
L'interface FutureTask est un mécanisme d'implémentation qui nous fournit un suivi et un contrôle de l'exécution des tâches. Comparé au pool de fils lui-même, il est relativement simple et je pense qu'il n'est pas difficile à comprendre.
Ce qui précède est tout le contenu de cet article sur le principe de mise en œuvre de FutureTask dans Java Thread Pool. J'espère que ce sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!