Voici quelques questions courantes sur les pools de fils de discussion que j'ai compilées lors d'entretiens Java, et je vais les partager avec vous maintenant.
(Partage de vidéos d'apprentissage : vidéo d'enseignement Java)
Qu'est-ce qu'un pool de threads ?
Le pool de threads est une forme de traitement multi-thread. Pendant le traitement, les tâches sont soumises au pool de threads et l'exécution de la tâche est gérée par le pool de threads.
Si chaque requête crée un thread à traiter, les ressources du serveur seront rapidement épuisées. L'utilisation d'un pool de threads peut réduire le nombre de threads créés et détruits, et chaque thread de travail peut être réutilisé et peut effectuer plusieurs tâches. .
Pourquoi utiliser un pool de threads ?
Le coût de création et de destruction des threads est relativement important, et ces délais peuvent être plus longs que le temps de traitement des affaires. Ces créations et destructions fréquentes de threads, associées aux threads de travail métier, consomment du temps en ressources système et peuvent conduire à des ressources système insuffisantes. (On peut supprimer le processus de création et de destruction des threads)
Quel est le rôle du pool de threads ?
La fonction du pool de threads est de limiter le nombre de threads d'exécution dans le système.
1. Améliorez l'efficacité. Créez un certain nombre de threads et placez-les dans le pool, et en retirez-un si nécessaire. C'est beaucoup plus rapide que de créer un objet thread en cas de besoin.
2. Pour faciliter la gestion, vous pouvez écrire du code de gestion du pool de threads pour gérer les threads du pool de manière uniforme. Par exemple, le programme crée 100 threads lorsqu'il est démarré. Chaque fois qu'il y a une demande, un thread est créé. affecté à work. , s'il y a 101 requêtes simultanées, la requête supplémentaire peut être mise en file d'attente pour éviter les pannes du système causées par la création de threads sans fin.
Parlez de plusieurs pools de threads courants et de scénarios d'utilisation
1. newSingleThreadExecutor
Créez un pool de threads à un seul thread, qui n'utilisera qu'un seul thread de travail pour exécuter des tâches. s'assurer que toutes les tâches sont exécutées dans l'ordre spécifié (FIFO, LIFO, priorité).
2. newFixedThreadPool
Crée un pool de threads de longueur fixe, qui peut contrôler le nombre maximum de threads simultanés en attente dans la file d'attente.
3. newCachedThreadPool
Créez un pool de threads pouvant être mis en cache. Si la longueur du pool de threads dépasse les besoins de traitement, les threads inactifs peuvent être recyclés de manière flexible. S'il n'y a pas de recyclage, créez un nouveau thread.
4. newScheduledThreadPool
Créez un pool de threads de longueur fixe pour prendre en charge l'exécution de tâches planifiées et périodiques.
Plusieurs paramètres importants dans le pool de threads
corePoolSize est le nombre de threads principaux dans le pool de threads. Ces threads principaux ne seront pas recyclés uniquement lorsqu'ils ne sont plus utiles
maximumPoolSize est le nombre maximum de threads pouvant être hébergés dans le pool de threads keepAliveTime est la durée la plus longue pendant laquelle d'autres threads autres que les threads principaux peuvent être conservés dans le pool de threads, car dans le pool de threads, Sauf pour les threads principaux qui ne peuvent pas être effacés même lorsqu'il n'y a pas de tâches, les autres ont un temps de survie, ce qui signifie le temps d'inactivité le plus long que les threads non principaux peuvent conserver util, qui calcule cette fois une unité. workQueue est une file d'attente. Les tâches peuvent être stockées dans la file d'attente des tâches en attente d'être exécutées. Elle implémente le principe FIFIO (premier entré, premier sorti). (Plus de questions d'entretien connexes à partager :questions et réponses d'entretien Java)
threadFactory est une usine de threads qui crée des fils de discussion. handler est une stratégie de rejet. Nous pouvons refuser d'effectuer certaines tâches une fois les tâches terminées. Parlons de la stratégie de refus du pool de threads Lorsque les tâches de requête continuent d'arriver et que le système ne peut pas les gérer pour le moment, la stratégie que nous devons adopter est le déni de service. L'interface RejectedExecutionHandler offre la possibilité d'utiliser des méthodes personnalisées pour rejeter le traitement des tâches. Quatre stratégies de traitement ont été incluses dans ThreadPoolExecutor. Stratégie AbortPolicy : Cette stratégie lancera directement une exception et empêchera le système de fonctionner normalement. Politique CallerRunsPolicy : tant que le pool de threads n'est pas fermé, cette stratégie exécute la tâche actuellement ignorée directement dans le thread appelant. Politique DiscardOleddestPolicy : cette stratégie supprimera la demande la plus ancienne, qui est la tâche qui est sur le point d'être exécutée, et tentera de soumettre à nouveau la tâche en cours. Politique DiscardPolicy : cette stratégie supprime silencieusement les tâches qui ne peuvent pas être traitées sans aucun traitement. En plus des quatre stratégies de rejet fournies par défaut par le JDK, nous pouvons personnaliser la stratégie de rejet en fonction de nos propres besoins commerciaux. La méthode de personnalisation est très simple, il suffit d'implémenter directement l'interface RejectedExecutionHandler. Quelle est la différence entre exécuter et soumettre ? Dans l'explication précédente, nous avons utilisé la méthode d'exécution pour exécuter des tâches. En plus de la méthode d'exécution, il existe également une méthode de soumission qui peut également exécuter les tâches que nous avons soumises. Quelle est la différence entre ces deux méthodes ? Dans quels scénarios sont-ils applicables ? Faisons une analyse simple. execute convient aux scénarios dans lesquels vous n'avez pas besoin de prêter attention à la valeur de retour. Il vous suffit de lancer le thread dans le pool de threads pour l'exécution. La méthode submit convient aux scénarios où vous devez faire attention à la valeur de retourScénarios d'utilisation de cinq pools de threadsnewSingleThreadExecutor : un pool de threads à thread unique qui peut être utilisé dans des scénarios où l'exécution séquentielle doit être garantie et où un seul thread est en cours d'exécution.
newFixedThreadPool : un pool de threads de taille fixe qui peut être utilisé pour limiter le nombre de threads sous une pression de concurrence connue.
newCachedThreadPool : un pool de threads pouvant être étendu à l'infini, qui est plus adapté au traitement de tâches avec un temps d'exécution relativement court.
newScheduledThreadPool : un pool de threads qui peut être démarré avec retard et planifié, adapté aux scénarios qui nécessitent plusieurs threads d'arrière-plan pour effectuer des tâches périodiques.
newWorkStealingPool : un pool de threads avec plusieurs files d'attente de tâches, qui peut réduire le nombre de connexions et créer des threads avec le nombre actuel de processeurs disponibles pour une exécution parallèle.
Fermeture du pool de threads
La fermeture du pool de threads peut être réalisée en appelant les méthodes shutdownNow et shutdown
shutdownNow : émettez une interruption() pour toutes les tâches en cours d'exécution et arrêtez l'exécution. annuler toutes les tâches qui n'ont pas encore commencé et renvoyer la liste des tâches qui n'ont pas encore commencé.
shutdown : lorsque nous appelons shutdown, le pool de threads n'acceptera plus de nouvelles tâches, mais il ne terminera pas de force les tâches qui ont été soumises ou qui sont en cours d'exécution.
Sélection du nombre de threads lors de l'initialisation du pool de threads
Si la tâche est gourmande en IO, généralement le nombre de threads doit être fixé à plus de 2 fois le nombre de CPU pour maximiser l’utilisation des ressources CPU.
Si la tâche est gourmande en CPU, il suffit généralement de définir le nombre de threads en ajoutant 1 au numéro de CPU. Plus de threads ne peuvent qu'augmenter le changement de contexte mais ne peuvent pas augmenter l'utilisation du CPU.
Ce qui précède n'est qu'une idée de base. Si vous avez vraiment besoin d'un contrôle précis, vous devez toujours observer le nombre de threads et de files d'attente dans le pool de threads après la mise en ligne.
Quels types de files d'attente de travail y a-t-il dans le pool de threads ?
1. ArrayBlockingQueue
est une file d'attente de blocage limitée basée sur une structure de tableau. (premier entré, premier sorti) Principes pour trier les éléments.
2. LinkedBlockingQueue
Une file d'attente de blocage basée sur une structure de liste chaînée. Cette file d'attente trie les éléments selon FIFO (premier entré, premier sorti), et le débit est généralement supérieur à celui d'ArrayBlockingQueue. La méthode de fabrique statique Executors.newFixedThreadPool() utilise cette file d'attente
3 SynchronousQueue
Une file d'attente de blocage qui ne stocke pas d'éléments. Chaque opération d'insertion doit attendre qu'un autre thread appelle l'opération de suppression, sinon l'opération d'insertion sera toujours bloquée et le débit est généralement supérieur à LinkedBlockingQueue. La méthode de fabrique statique Executors.newCachedThreadPool utilise cette file d'attente.
4. PriorityBlockingQueue
Une file d'attente de blocage infinie avec priorité.
Recommandations de cours associées : Tutoriel d'introduction à Java
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!