Pool de threads ThreadPool
De même, avant qu'il n'y ait un pool de threads, nous utilisions également new Thread.start() pour obtenir des threads. Désormais, nous n'avons plus besoin de new, nous pouvons donc réaliser la réutilisation et rendre notre système plus efficace.
1.2. Pourquoi utiliser un pool de threadsExemple :
Il y a 10 ans, un ordinateur à processeur monocœur, un faux multi-threading, comme Le clown de cirque joue avec plusieurs balles et le processeur doit basculer d'avant en arrière.
De nos jours, il s'agit d'un ordinateur multicœur. Plusieurs threads fonctionnent sur des processeurs indépendants, ce qui est plus efficace sans commutation.
Avantages du pool de threads :
Réutilisation des threads
Contrôler le nombre maximum de concurrences
Exécuteur Qu'est-ce qu'un cadre ?
Ceci est décrit dans Java DocUn objet qui exécute les tâches Runnable soumises. Cette interface fournit un moyen de dissocier la soumission des tâches des mécanismes d'exécution de chaque tâche, y compris. détails sur l'utilisation des threads, la planification, etc. Un exécuteur est normalement utilisé au lieu de créer explicitement des threads.
Objet qui exécute les tâches exécutables soumises. Cette interface fournit un mécanisme pour soumettre des tâches et comment exécuter chaque tâche, y compris des détails sur l'utilisation des threads, la planification, etc. Généralement, un exécuteur est utilisé au lieu de créer explicitement des threads.
Le pool de threads en Java est implémenté via le framework Executor, qui utilise les classes Executor, Executors, ExecutorService et ThreadPoolExecutor.L'interface que nous utilisons couramment est la sous-interface ExecutorService
,Les exécuteurs sont des classes d'outils pour les threads (classes d'outils similaires aux tableaux, tableaux et classes d'outils de collection, collections)
.ThreadPoolExecutor est au centre de ces cours. Nous pouvons obtenir le pool de threads ThreadPoolExecutor via la classe d'outils auxiliaire Executors
Une introduction plus détaillée à chaque classe est la suivante : Interfaces de tous les pools de threads d'Executor , il n'y a qu'une seule méthode. Cette interface définit la manière d'exécuter les tâches Runnable ExecutorService L'ajout du comportement d'Executor est l'interface la plus directe de la classe d'implémentation Executor. fournit des services pour Executor
La classe d'usine de pool de threads Executors fournit une série de méthodes d'usine pour créer des pools de threads. Les pools de threads renvoyés implémentent tous
ScheduledExecutorService : interface de planification planifiée. Classe abstraite du cadre d'exécution AbstractExecutorService.
ThreadPoolExecutor L'implémentation spécifique du pool de threads dans JDK Divers pools de threads couramment utilisés sont implémentés sur la base de cette classe
Trois méthodes principales de pool de threads.
Méthode 2.2.1.newFixedThreadPool(int)
Exécute des tâches à long terme avec de bonnes performances, crée un pool de threads, un pool a N threads fixes et un nombre fixe de threads
public static void main(String[] args) { //一池5个受理线程,类似一个银行5个受理窗口。不管你现在多少个线程,都只有5个 ExecutorService threadPool=Executors.newFixedThreadPool(5); try { //模拟有10个顾客过来银行办理业务,目前池子里面有5个工作人员提供服务。 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
peut voir les résultats de l'exécution. Il y a 5 threads dans le pool, ce qui équivaut à 5 membres du personnel fournissant des services externes et gérant les affaires. Sur la photo, la fenêtre n°1 gère les affaires deux fois et la fenêtre d'acceptation de la banque peut être réutilisée plusieurs fois. Ce n’est pas nécessairement que tout le monde le gère deux fois, mais celui qui le gère plus rapidement en gérera plus.
Lorsque nous ajoutons un délai de 400 ms lors de l'exécution du thread, vous pouvez voir l'effet
public static void main(String[] args) { //一池5个受理线程,类似一个银行5个受理窗口。不管你现在多少个线程,都只有5个 ExecutorService threadPool=Executors.newFixedThreadPool(5); try { //模拟有10个顾客过来银行办理业务,目前池子里面有5个工作人员提供服务。 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); try { TimeUnit.MILLISECONDS.sleep(400); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
Cela signifie que le réseau est encombré ou que l'activité est lente. Ensuite, la distribution. des tâches métier gérées par le pool de threads est relativement uniforme.
Exectors.newSingleThreadExector()–>Exécution d'une tâche à la fois, un pool et un thread
public static void main(String[] args) { //一池一个工作线程,类似一个银行有1个受理窗口 ExecutorService threadPool=Executors.newSingleThreadExecutor(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
Exectors.newCachedThreadPool()–>Exécuter de nombreuses tâches asynchrones à court terme, le pool de threads crée de nouveaux threads selon les besoins, mais avant les threads précédemment construits. Ils seront réutilisés lorsqu'ils seront disponibles. Il peut être étendu et devient plus fort lorsqu'il est fort . Un pool de n threads, extensible, évolutif, signifie
Alors combien de pools doivent être définis si la banque n'a qu'une seule fenêtre, alors quand trop de monde viendra, elle sera trop occupée. Si une banque a de nombreux guichets mais que peu de gens viennent, cela semblera être un gaspillage de ressources. Alors comment prendre des dispositions raisonnables ? Cela nécessite l'utilisation de la méthode newCachedThreadPool(), qui est extensible et évolutive
public static void main(String[] args) { //一池一个工作线程,类似一个银行有n个受理窗口 ExecutorService threadPool=Executors.newCachedThreadPool(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
public static void main(String[] args) { //一池一个工作线程,类似一个银行有n个受理窗口 ExecutorService threadPool=Executors.newCachedThreadPool(); try { //模拟有10个顾客过来银行办理业务 for(int i=1;i{ System.out.println(Thread.currentThread().getName()+"\t 办理业务"); }); } } catch (Exception e) { // TODO: handle exception }finally{ threadPool.shutdown(); } }
3 Le principe sous-jacent. de ThreadPoolExecutor
newFixedThreadPool code source sous-jacent
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<runnable>()); }</runnable>
Comme vous pouvez le voir, les paramètres sous-jacents incluent la file d'attente de blocage LinkedBlockingQueue.
code source sous-jacent newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<runnable>())); }</runnable>
newCachedThreadPool code source sous-jacent
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<runnable>()); }</runnable>
SynchronousQueue Cette file d'attente de blocage est une version unique de la file d'attente de blocage, et la file d'attente de blocage a une capacité de 1 .
Ces trois méthodes renvoient en fait un objet ensemble, c'est-à-dire l'objet de ThreadPoolExecutor.
4. Les 7 paramètres importants du pool de threads
Constructeur de ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize <p>ci-dessus int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit , BlockingQueue workQueue, ThreadFactory threadFactory, <br> Le gestionnaire RejectedExecutionHandler est nos sept paramètres de thread <br> Ce qui précède est la méthode de construction de la classe ThreadPoolExecutor, avec 7 paramètres : </p> <p>1) <strong> corePoolSize : thread pool Le nombre de threads principaux résidents dans </strong>, appelé nombre de cœurs. <br> Par exemple, on peut traiter un pool de threads comme une agence bancaire. Tant que la banque ouvre ses portes, il doit y avoir au moins une personne de service. C'est ce qu'on appelle le nombre de threads principaux résidents. Par exemple, si une banque a ses cinq succursales ouvertes du lundi au vendredi, alors le nombre de threads principaux résidents du lundi au vendredi est de 5. Si les affaires ne sont pas si fréquentes aujourd'hui et que la fenêtre est de 1, alors le nombre de threads principaux résidents aujourd'hui est 1 </p> <p>2) <strong>maxImumPoolSize : Le nombre maximum de threads pouvant être exécutés simultanément dans le pool de threads. Cette valeur doit être supérieure ou égale à 1</strong></p> <p>. 3) <strong>keepAliveTime : temps d'inactivité excessif Le temps de survie des threads Lorsque le nombre de threads dans le pool actuel dépasse corePoolSize, lorsque le temps d'inactivité atteint keepAliveTime, les threads en excès seront détruits jusqu'à ce qu'il reste corePoolSize </strong> S'il y a des threads résidents dans le pool de threads, et qu'il y a un nombre maximum de threads, cela signifie qu'il est généralement résident. Si le travail est tendu, il sera étendu au nombre maximum de threads. Si l'activité chute, nous. définissez le temps de survie des threads inactifs en excès, par exemple en le définissant sur 30 secondes. S'il n'y a pas d'excès pendant 30 secondes, lorsque vous le demandez, certaines banques fermeront la fenêtre, de sorte qu'elle s'agrandit mais se rétrécisse également. <br></p>4) <p>unité : unité de keepAliveTime <strong></strong>Unité : secondes, millisecondes, microsecondes. <br></p> <p>5) workQueue : File d'attente des tâches, tâches qui ont été soumises mais pas encore exécutées <strong></strong> Il s'agit d'une file d'attente bloquante, comme une banque, qui n'a que 3 fenêtres d'acceptation, et voici 4 clients. Cette file d'attente bloquante est la zone d'attente de la banque. Une fois qu'un client arrive, il ne peut pas être autorisé à sortir. Le nombre de fenêtres contrôle le nombre de threads simultanés. <br></p>6) <p>threadFactory : Représente la fabrique de threads qui génère des threads de travail dans le pool de threads. Elle est utilisée pour créer des threads. Généralement, la valeur par défaut est <strong></strong> Les threads sont tous créés de manière uniforme. Il existe de nouveaux threads dans le pool de threads, qui sont produits par l'usine de pool de threads. <br></p> <p>7) gestionnaire : stratégie de rejet, indiquant comment rejeter la stratégie d'exécution de la requête exécutable lorsque la file d'attente actuelle est pleine et que le thread de travail est supérieur ou égal au nombre maximum de threads dans le pool de threads (taille maximale de la piscine) <strong></strong></p> <p>Par exemple, aujourd'hui, c'est le pic de flux de clients à la banque. Les trois guichets sont pleins et la salle d'attente est également pleine. Nous n’avons pas choisi de continuer à recruter parce que ce n’était pas sécuritaire, nous avons donc choisi de refuser poliment. </p> <p>Dans la section suivante, nous présenterons le principe de fonctionnement sous-jacent du pool de threads</p> <blockquote><p><strong>Recommandations d'apprentissage associées : </strong><a href="https://www.php.cn/java/base/" target="_blank"><strong>Bases de Java</strong></a> </p></blockquote></runnable>
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!