Les threads sont l'unité de base de la planification du timing dans le système d'exploitation.
Le pool de threads peut être compris comme un pool de threads, qui est un conteneur. Ce conteneur ne peut contenir que des threads. Ce récipient a différentes tailles, il peut contenir 7 ou 8 pièces, ou 3 ou 4 pièces. Le conteneur peut également être rempli, mais il existe une valeur maximale, par exemple 12. Par exemple, le pool de threads contient généralement 5 threads et peut contenir jusqu'à 12 threads. À cette époque, il y avait cinq personnes qui avaient besoin d'utiliser le pool de threads, alors il a retiré cinq threads. Et si deux personnes venaient plus tard, il n'avait définitivement aucun thread à utiliser et il devait attendre que ces cinq personnes aient fini d'utiliser ? il. Mais mon pool peut en contenir 12. Comment puis-je le faire si je n'ai que 5 threads ? Je dois absolument installer quelques threads supplémentaires, sinon ce ne sera pas suffisant s'il y a plus de monde à ce moment-là, 2 sont arrivés et moi. produisait 2. Le nombre total de threads atteint 7. Pour le moment, les 2 personnes restantes n'ont pas besoin d'attendre et peuvent être utilisées directement. Si 6 personnes viennent, à ce moment-là, mon pool n'a peut-être qu'une capacité de 5 threads, je peux produire 5 threads, mais il y a encore une personne qui doit attendre quelque part. Je ne peux pas laisser les gens attendre sans but. Je vais trouver 5 tabourets. Vous pouvez vous asseoir là et attendre. Ensuite, la première vague de cinq personnes est à court de fils, et 5 fils sont soudainement libérés. La personne restante peut utiliser le. À ce moment-là, 10 personnes supplémentaires sont venues les unes après les autres. Mon fil ne peut être utilisé que par 4 personnes. Que dois-je faire s'il reste une personne ? Je n'ai pas de place ici. Vous voulez C'est vraiment inconfortable de dire non sans d'abord chercher ailleurs, et je dois penser à plusieurs stratégies de rejet. . . , je pense qu'il y a encore beaucoup de gens qui utilisent mon pool de threads, avec autant de personnes qui l'utilisent, que se passe-t-il si quelqu'un continue d'occuper mon pool de threads, je dois trouver un moyen de le gérer ? Sinon, un fil ne peut être utilisé que pendant 1 minute et il sera recyclé immédiatement après utilisation. Si vous souhaitez le réutiliser, faites la queue et attendez à nouveau. De cette façon, mon activité de fil s'améliore de plus en plus. Tant que quelqu'un l'utilisera, il continuera à fonctionner.
N'est-ce pas un peu comme un restaurant ou un magasin buffet ? Un magasin buffet est plus visuel Tant qu'il y a une place dans mon hôtel, les gens peuvent s'asseoir jusqu'à la capacité maximale, les clients restants peuvent seulement. attendez à la porte. À l'intérieur de l'hôtel, un client entre et l'autre vient attendre à l'extérieur. S'il n'y a plus d'espace d'attente, le client verra qu'il n'y a pas de place et partira directement. Si certaines personnes veulent vraiment manger, elles le feront. je peux attendre encore un peu. Les clients du restaurant ne doivent pas manger trop longtemps (généralement lorsqu'il n'y a pas de siège), environ 2 heures, et ils partiront après avoir mangé.
Sur la base de ma description ci-dessus, je peux probablement déterminer ce qu'il y a dans le pool de threads ?
Combien de threads sont installés, combien de threads peuvent être installés, combien de temps les threads peuvent être conservés, zone d'attente des threads, comment rejeter, créer des threads
Le fonctionnement du programme doit s'appuyer sur processus, processus L'unité d'exécution réelle est le thread.
Appel de services au sein du système. Le système s'appuie sur des processus pour s'exécuter. Il existe de nombreux services dans le système et il existe des interactions entre les services. L'exécution des services repose sur des threads. Le fonctionnement multiservice repose sur un fonctionnement multithread. Les appels et l'échange de données entre les services s'appuient sur la mémoire entre les processus pour l'interaction des données. Dans le même temps, les threads peuvent également créer leur propre espace mémoire. S'appuyer sur la planification des ressources et l'interaction des données entre les processus.
Plusieurs threads peuvent améliorer les performances d'exécution du programme. Par exemple, s'il y a une maison de 90 mètres carrés, il faut 30 minutes à une personne pour la nettoyer, et seulement 10 minutes à trois personnes pour la nettoyer. Ces trois personnes sont les « multithreads » du programme.
Dans de nombreux programmes, plusieurs threads doivent être synchronisés les uns avec les autres ou s'exclure mutuellement pour terminer le travail en parallèle.
Les threads sont plus légers que les processus, donc le coût de création et de destruction des threads devient plus petit.
Les threads améliorent les performances Bien que les threads soient macroscopiquement parallèles, ils sont microscopiquement en série. Les threads ne peuvent pas améliorer les performances du point de vue du processeur, mais si certains threads sont impliqués dans l'attente de ressources (comme les E/S, l'attente d'entrée), le multithreading permet à d'autres threads du processus de continuer à s'exécuter au lieu que l'ensemble du processus soit bloqué. améliorant le taux d'utilisation du processeur, de ce point de vue, les performances seront améliorées.
Dans le cas du multi-CPU ou du multi-core, l'utilisation des threads n'est pas seulement parallèle au niveau macro, mais aussi au niveau micro.
Plusieurs threads peuvent améliorer les performances d'exécution du programme
Par exemple, lorsque vous mangez un buffet, lorsqu'il y a suffisamment de places et suffisamment de personnes, le buffet sera le plus rentable. en même temps, le tarif des repas et la satisfaction du client peuvent également être fournis. S'il y a 200 personnes qui mangent et 100 lieux de restauration, et que chaque personne mange pendant une heure en moyenne, alors les 200 personnes termineront le repas en deux heures. S'il n'y a que 10 places assises, il faudra environ 20 heures pour que 200 personnes mangent. Imaginez à quel point le reste des clients seraient mécontents s'ils attendaient leur repas avec impatience.
Les sièges du buffet sont des fils. Quand il y a suffisamment de fils, plus de gens peuvent manger, mais cela ne veut pas dire que plus il y a de fils, mieux c'est. Après tout, il n'est pas certain que 200 clients viendront manger chacun. temps, même si 200 clients viennent manger, nous devons également évaluer des facteurs matériels de base tels que s'il y a suffisamment de chefs dans le restaurant, si la femme de ménage peut nettoyer et s'il y a suffisamment d'assiettes dans le restaurant. Cela équivaut à la configuration du système, qui nécessite certaines conditions matérielles essentielles telles que la mémoire et le traitement du processeur.
La création/destruction de threads s'accompagne d'une surcharge du système. La création/destruction de threads trop fréquemment affectera grandement l'efficacité du traitement (tant que le thread continue de s'exécuter, il ne sera pas détruit)
N'oubliez pas le temps que cela prend. pour créer un thread T1, l'exécution de la tâche consomme du temps T2 et la destruction du thread consomme du temps T3. Si T1+T3>T2, cela signifie-t-il qu'il n'est pas rentable d'ouvrir un thread pour effectuer cette tâche ? Il se trouve que le pool de threads met en cache les threads et peut utiliser les threads inactifs existants pour effectuer de nouvelles tâches, évitant ainsi la surcharge du système causée par T1+T3. Bien sûr, les threads principaux survivants consommeront également des ressources CPU
Il y en a aussi. de nombreux threads simultanés. Préempter les ressources système et provoquer un blocage
Nous savons que les threads peuvent partager des ressources système. Si trop de threads sont exécutés en même temps, cela peut entraîner des ressources système insuffisantes et provoquer un blocage. peut contrôler efficacement le nombre maximum de threads simultanés. , pour éviter les problèmes ci-dessus
Effectuer une gestion simple des threads
Par exemple : l'exécution retardée, les stratégies d'exécution de boucle chronométrée, etc. peuvent être bien implémentées en utilisant le thread. pools
Améliorer l'utilisation des threads
Assurez-vous qu'il est utilisé lorsqu'il y a des affaires et publié lorsqu'il n'y a pas d'affaires.Utilisez les threads de manière rationnelle et évitez le gaspillage de ressources
Améliorez. la vitesse de réponse du programme
Par Si le pool de threads est géré de manière uniforme, l'allocation des ressources est planifiée à l'aide d'un pool de planification unifié. Lorsque des threads sont utilisés, la création et la destruction fastidieuses de threads peuvent être évitées, et les threads peuvent être évités. être utilisé directement.
Facilite la gestion unifiée des objets thread
Le pool de threads peut garantir un déploiement et une gestion unifiés des threads.
Vous pouvez contrôler le nombre maximum de concurrence
Le serveur a une limite supérieure pour l'utilisation des threads, et l'utilisation des threads consomme également beaucoup de ressources, de sorte que le pool de threads peut bien contrôler les ressources des threads pour éviter le gaspillage.
ThreadPoolExecutor est une classe de pool de threads en Java, qui peut être utilisée pour regrouper les threads.
// 根据上面的描述大概分析一下线程都需要什么及参数的解析 // corePoolSize 核心线程数,就是上面说的装了多少个线程 // maximumPoolSize 最大线程数,就是上面说的能装多少线程 // keepAliveTime 存活时间,就是上面说的线程可以保留多长时间 // TimeUnit 这个是时间单位,有时、分、秒、天等等,是存活时间的单位 // BlockingQueue<Runnable> 这是一个等待队列,就是上面显示的线程等待区 // ThreadFactory 线程工厂,就是上面描述的如何创建线程,由谁创建 // RejectedExecutionHandler 拒绝策略,就是上面显示的如何拒绝,是直接拒绝还是婉拒 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue) public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory) public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
Comme vous pouvez le voir, il nécessite les paramètres suivants :
corePoolSize (obligatoire) : le nombre de threads principaux. Par défaut, le thread principal survivra toujours, mais lorsque allowCoreThreadTimeout est défini sur true, le thread principal expirera également et sera recyclé.
maximumPoolSize (obligatoire) : le nombre maximum de threads que le pool de threads peut accueillir. Lorsque le nombre de threads actifs atteint cette valeur, les nouvelles tâches ultérieures seront bloquées.
keepAliveTime (obligatoire) : délai d'inactivité du thread. Si ce délai est dépassé, les threads non essentiels seront recyclés. Si AllowCoreThreadTimeout est défini sur true, le thread principal expirera également et sera recyclé.
unit (obligatoire) : Spécifie l'unité de temps pour le paramètre keepAliveTime. Les plus couramment utilisés sont : TimeUnit.MILLISECONDS (millisecondes), TimeUnit.SECONDS (secondes), TimeUnit.MINUTES (minutes).
workQueue (obligatoire) : file d'attente des tâches. Les objets exécutables soumis via la méthode execute() du pool de threads seront stockés dans ce paramètre. Il est implémenté à l’aide d’une file d’attente de blocage.
threadFactory (facultatif) : Usine de threads. Utilisé pour spécifier comment les nouveaux threads sont créés pour le pool de threads.
handler (facultatif) : Stratégie de rejet. Une stratégie de saturation qui doit être exécutée lorsque le nombre maximum de threads est atteint.
import java.util.concurrent.*; public class ThreadTest { public static void main(String[] args) { ExecutorService threadPoolExecutor = new ThreadPoolExecutor(3, 5, 1L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory()); for (int i = 0; i < 20; i++) { int finalI = i; threadPoolExecutor.submit( ()->{ System.out.println(Thread.currentThread().getName() + "========" + finalI); }); } threadPoolExecutor.shutdown(); } }
Résultat d'exécution :
.pool-1-thread-1========0
pool-1-thread-3========2
pool-1-thread-3======= =4
pool-1-thread-2========1
pool-1-thread-3========5
pool-1-thread-2====== ==8
pool-1-thread-5========7
pool-1-thread-1========3
pool-1-thread-4===== ===6
Exception dans le thread "main" java.util.concurrent.RejectedExecutionException : tâche java.util.concurrent.FutureTask@61e717c2 rejetée de java.util.concurrent.ThreadPoolExecutor@66cd51c3[En cours d'exécution, taille du pool = 5, threads actifs = 2, tâches en file d'attente = 0, tâches terminées = 7]
à java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
à java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830 )
sur java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
sur java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
sur com.halo.communication.ThreadTest.main(ThreadTest .java:10)线程执行,然后开始出现异常处理。上面执行的线程数到thread-5,5是线程池的默认最大线程数。然后执行for 20次,进行执行到8的时候出现异常,说明线程池已经超载满负荷执行,所以线程池执行拒绝策略。
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!