À partir de Java 5, Java fournit sa propre piscine de fil. Un pool de threads est un conteneur de thread, qui exécute uniquement un nombre nominal de threads à la fois. java.util.concurrent.threadpoolExecutor est un pool de threads. Il est très flexible, mais il est également compliqué à utiliser, donc cet article le présentera.
Le premier est le constructeur. Prenez le constructeur le plus simple à titre d'exemple:
Public ThreadPoolExecutor (int corepoolSize, int maximumpoolSize, long keepalivetime, timeunit unit, blocingQueue <cunnable> workqueue)
Cela semble assez compliqué. Permettez-moi de le présenter ici.
CorePoolSize fait référence à la taille du pool de filetage réservé.
MaximumpoolSize fait référence à la taille maximale du pool de threads.
KeepaliveTime fait référence à l'heure du délai d'expiration où se termine le fil inactif.
L'unité est une énumération représentant l'unité de KeepaliveTime.
WorkQueue représente la file d'attente pour le stockage des tâches.
Nous pouvons comprendre l'importance de ces paramètres du processus de travail du pool de threads. Le processus de travail du pool de threads est le suivant:
1. Lorsque la piscine de fil a été créée pour la première fois, il n'y avait pas de fil à l'intérieur. La file d'attente de tâches est transmise en tant que paramètre. Cependant, même s'il y a des tâches dans la file d'attente, le pool de threads ne les exécutera pas immédiatement.
2. Lors de l'appel d'exécution () pour ajouter une tâche, le pool de thread fera le jugement suivant:
a.
b.
c.
d.
3. Lorsqu'un thread termine une tâche, il faudra une tâche de la file d'attente à exécuter.
4. Lorsqu'un fil n'a rien à faire et qu'il faut un certain temps (keepalivetime), le pool de thread jugera que si le nombre de threads en cours d'exécution est supérieur à CorePoolSize, le fil sera arrêté. Ainsi, une fois toutes les tâches du pool de fils terminées, il finira par rétrécir la taille de CorePoolSize.
Ce processus montre qu'il n'est pas nécessaire d'exécuter d'abord la tâche si vous rejoignez d'abord la tâche. En supposant que la taille de la file d'attente est de 10, CorePoolSize est de 3 et MaximumpoolSize est 6, alors lorsque 20 tâches sont ajoutées, l'ordre d'exécution est le suivant: Tout d'abord, les tâches 1, 2, 3 sont exécutées, puis des tâches 4 ~ 13 sont placées dans la file d'attente. À l'heure actuelle, la file d'attente est complète, les tâches 14, 15, 16 seront exécutées immédiatement, et les tâches 17 à 20 lèveront des exceptions. La commande finale est: 1, 2, 3, 14, 15, 16, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13. Voici un exemple d'utilisation du pool de fils:
public static void main (String [] args) {BlockingQueue <Scapyable> queue = new LinkedBlockingQueue <nandable> (); threadPoolExecutor EMECTOR = new Thre AdpoolExecutor (3, 6, 1, timeUnit.Days, queue); 0; Out.
Une explication de cet exemple est la suivante:
1. BlockingQueue est juste une interface. L'avantage d'utiliser LinkedBlockingQueue est qu'il n'y a pas de limite de taille. De cette façon, parce que la file d'attente ne sera pas pleine, EXECUTE () ne lancera pas d'exception, et le nombre de threads exécutés dans le pool de threads ne dépassera jamais CorePoolSize, donc le paramètre KeepaliveTime n'a pas de sens.
2. La méthode Shutdown () ne bloquera pas. Après avoir appelé la méthode Shutdown (), le thread principal se termine immédiatement et le pool de thread continuera à fonctionner jusqu'à ce que toutes les tâches soient exécutées avant de s'arrêter. Si la méthode Shutdown () n'est pas appelée, le pool de threads restera afin que de nouvelles tâches puissent être ajoutées à tout moment.
À ce stade, je n'ai introduit qu'une petite partie de ce pool de fils. ThreadPoolExecutor est très évolutif, mais la prémisse de l'extension est de savoir comment cela fonctionne. L'article suivant expliquera comment étendre la classe ThreadPoolExecutor.
La classe ava.util.concurrent.threadpoolExecutor offre une riche extensibilité. Vous pouvez personnaliser son comportement en créant sa sous-classe. Par exemple, je souhaite imprimer un message après la fin de chaque tâche, mais je ne peux pas modifier l'objet de tâche, alors je peux écrire ceci:
ThreadPoolExECUTOR EMECTOR = new ThreadPoolExECUTOR (size, maxsize, 1, timeunit.days, file d'attente) {@Override Protected void AftereXecute (runnable r, t hrowable t) {System.out.println ("tâche terminée.");
En plus de la méthode AfterExecute, la classe ThreadPoolExecutor a également avant Execute () et terminé () des méthodes qui peuvent être remplacées, qui sont exécutées avant l'exécution de la tâche et après l'arrêt de l'ensemble du pool de threads.
En plus d'ajouter des actions avant et après l'exécution des tâches, ThreadPoolExecutor vous permet également de personnaliser la stratégie d'exécution après l'ajout de tâches. Vous pouvez appeler la méthode SetRejectEdExecutionHandler () du pool de threads et remplacer la stratégie existante par l'objet RejectEdExecutionHandler personnalisé. ThreadPoolExecutor fournit 4 politiques existantes, à savoir:
ThreadpoolExecutor.AbortPolicy: indique que la tâche est rejetée et que l'exception est lancée
ThreadpoolExecutor.DiscardPolicy: signifie rejeter la tâche mais ne faire aucune action
ThreadPoolExecutor.CallerSpolicy: indique que la tâche est rejetée et que la tâche est exécutée directement dans le thread de l'appelant.
ThreadPoolExecutor.DiscardolDestPolicy: Cela signifie que la première tâche dans la file d'attente de tâche est d'abord rejetée, puis la tâche est ajoutée à la file d'attente.
Voici un exemple:
ThreadPoolExECUTOR Executor = new ThreadPoolExecutor (size, maxsize, 1, timeunit.days, file d'attente);
EMECTOR.SetRejectEdExecutionHandler (new ThreadPoolExecutor.DiscardPolicy ());
De plus, vous pouvez également rédiger vos propres politiques en mettant en œuvre l'interface RejectEdExecutionHandler. Voici un exemple:
ThreadPoolExecutor exécutor = new ThreadPoolExecutor (3, 6, 1, timeunit.seconds, file d'attente, new rejettedexecutionHandler () {public void rejectEdexEcuti on (runnable r, threadpoolExecutor executor) {System.out.println (string.format ("tâche% d rejeté .