Quelle est la différence exacte entre taille du pool de base y taille maximale de la piscine quand on parle en termes de ThreadPoolExecutor
?
Peut-on l'expliquer à l'aide d'un exemple ?
Réponses
Trop de publicités?Desde cet article de blog :
Prenez cet exemple. La taille du pool de threads de départ est de 1, la taille du pool de base est de 5. 5, la taille maximale du pool est de 10 et la file d'attente est de 100.
Au fur et à mesure que les demandes arrivent, les threads seront créés jusqu'à 5 et ensuite les tâches seront ajoutées à la file d'attente jusqu'à ce qu'elle atteigne 100. Lorsque la file d'attente est pleine, de nouveaux threads sont créés. créés jusqu'à
maxPoolSize
. Une fois que tous les threads sont utilisés et que la file d'attente est pleine, les tâches sont rejetées. file d'attente est pleine, les tâches sont rejetées. Au fur et à mesure que la file d'attente diminue, le le nombre de threads actifs.
SI threads en cours d'exécution > corePoolSize & < maxPoolSize puis créer un nouveau Thread si la file d'attente des tâches totales est pleine et qu'une nouvelle tâche arrive.
Du doc : (S'il y a plus de corePoolSize mais moins de maximumPoolSize threads en cours, un nouveau thread ne sera créé que si la file d'attente est pleine).
Prenons un exemple simple,
ThreadPoolExecutor executorPool = new ThreadPoolExecutor(5, 10, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50));
Ici, 5 est la taille du corePoolSize. - Cela signifie que Jvm va créer un nouveau thread pour les 5 premières tâches et que les autres tâches seront ajoutées à la file d'attente jusqu'à ce que celle-ci soit pleine (50 tâches).
10 est la taille maximale du pool (maxPoolSize) - La JVM peut créer un maximum de 10 threads. Cela signifie que s'il y a déjà 5 tâches/threads en cours d'exécution et que la file d'attente est pleine de 50 tâches en attente, et si une nouvelle demande/tâche arrive dans la file d'attente, la JVM créera un nouveau thread jusqu'à 10 (total des threads = 5 précédents + 5 nouveaux) ;
nouveau ArrayBlockingQueue(50) \= est une taille totale de file d'attente - elle peut contenir 50 tâches.
une fois que les 10 threads sont en cours d'exécution, si une nouvelle tâche arrive, elle est rejetée.
Règles pour la création de Threads en interne par SUN :
-
Si le nombre de threads est inférieur au corePoolSize, créez un nouveau Thread pour exécuter une nouvelle tâche.
-
Si le nombre de threads est égal (ou supérieur) au corePoolSize, la tâche est placée dans la file d'attente.
-
Si la file d'attente est pleine et que le nombre de threads est inférieur à la taille maxPoolSize, créez un nouveau thread pour exécuter les tâches.
-
Si la file d'attente est pleine, et que le nombre de threads est supérieur ou égal à maxPoolSize, rejeter la tâche.
J'espère que cela vous aidera... et corrigez-moi si je me trompe...
Règles de la taille d'un pool ThreadPoolExecutor
Les règles relatives à la taille d'un ThreadPoolExecutor's
Les piscines sont généralement mal comprises, car elles ne fonctionnent pas de la manière dont vous pensez qu'elles devraient fonctionner ou de la manière dont vous le souhaitez.
Prenez cet exemple. La taille du pool de threads de départ est de 1, celle du pool de base est de 5, celle du pool maximum est de 10 et la file d'attente est de 100.
La méthode de Sun : au fur et à mesure que les demandes arrivent, des fils seront créés jusqu'à 5, puis des tâches seront ajoutées à la file d'attente jusqu'à ce qu'elle atteigne 100. Quand la file d'attente est pleine, de nouveaux threads sont créés jusqu'à maxPoolSize
. Lorsque tous les fils sont utilisés et que la file d'attente est pleine, les tâches sont rejetées. Au fur et à mesure que la file d'attente diminue, le nombre de fils actifs diminue également.
Méthode anticipée par l'utilisateur : au fur et à mesure que les demandes arrivent, des fils seront créés jusqu'à 10, puis des tâches seront ajoutées à la file d'attente jusqu'à ce qu'elle atteigne 100, après quoi elles seront rejetées. Le nombre de threads sera renommé au maximum jusqu'à ce que la file d'attente soit vide. Lorsque la file d'attente est vide, les threads s'éteignent jusqu'à ce qu'il n'y en ait plus. corePoolSize
gauche.
La différence est que les utilisateurs veulent commencer à augmenter la taille du pool plus tôt et veulent que la file d'attente soit plus petite, alors que la méthode Sun veut garder une petite taille de pool et ne l'augmenter que lorsque la charge devient trop importante.
Voici les règles de Sun pour la création de fils en termes simples :
- Si le nombre de threads est inférieur à la valeur de l'option
corePoolSize
créer un nouveau Thread pour exécuter une nouvelle tâche. - Si le nombre de threads est égal (ou supérieur) à la valeur de l'option
corePoolSize
la tâche est placée dans la file d'attente. - Si la file d'attente est pleine, et que le nombre de threads est inférieur à la valeur de l'indicateur d'état de la file.
maxPoolSize
créer un nouveau fil de discussion pour exécuter les tâches. - Si la file d'attente est pleine, et que le nombre de threads est supérieur ou égal à
maxPoolSize
rejette la tâche. En résumé, les nouveaux threads ne sont créés que lorsque la file d'attente se remplit. Ainsi, si vous utilisez une file d'attente non limitée, le nombre de threads ne dépassera pas les limites suivantescorePoolSize
.
Pour une explication plus complète, allez voir du côté de la bouche des chevaux : ThreadPoolExecutor
Documentation de l'API.
Il y a un très bon message sur le forum qui vous explique comment le système de gestion de l'information de l'UE est utilisé. ThreadPoolExecutor
travaille avec des exemples de code : http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0
Plus d'informations : http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
Desde le doc :
Lorsqu'une nouvelle tâche est soumise dans la méthode execute(java.lang.Runnable), et que le nombre de threads en cours d'exécution est inférieur à corePoolSize, un nouveau thread est est créé pour traiter la demande, même si d'autres threads de travail sont inactifs. S'il y a plus de threads que corePoolSize mais moins que maximumPoolSize en cours d'exécution, un nouveau thread sera créé uniquement si la file d'attente est pleine.
En outre :
En fixant la même taille pour le corePoolSize et le maximumPoolSize, on crée un pool de threads de taille fixe. En définissant maximumPoolSize à une valeur essentiellement valeur essentiellement illimitée telle que Integer.MAX_VALUE, vous permettez au pool de d'accueillir un nombre arbitraire de tâches simultanées. Le plus souvent, les tailles de pool de base et maximale sont définies uniquement lors de la construction, mais elles mais elles peuvent aussi être modifiées dynamiquement à l'aide de setCorePoolSize(int) et de setMaximumPoolSize(int).
Si vous décidez de créer un ThreadPoolExecutor
manuellement au lieu d'utiliser l'option Executors
vous devrez en créer et en configurer une en utilisant l'un de ses constructeurs. Le constructeur le plus complet de cette classe est :
public ThreadPoolExecutor(
int corePoolSize,
int maxPoolSize,
long keepAlive,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler
);
Comme vous pouvez le voir, vous pouvez configurer :
- La taille du core pool (la taille que le pool de threads va essayer de respecter).
- La taille maximale du pool.
- Le temps de maintien en vie, qui est un temps après lequel un fil de discussion inactif est éligible pour être détruit.
- La file d'attente de travail pour contenir les tâches en attente d'exécution.
- La politique à appliquer lorsqu'une soumission de tâche est rejetée.
Limiter le nombre de tâches en file d'attente
Limiter le nombre de tâches simultanées en cours d'exécution, c'est-à-dire dimensionner votre pool de threads, représente un avantage considérable pour votre application et son environnement d'exécution en termes de prévisibilité et de stabilité : une création illimitée de threads finira par épuiser les ressources d'exécution et votre application pourrait connaître de graves problèmes de performances pouvant aller jusqu'à l'instabilité de l'application.
Cette solution ne résout qu'une partie du problème : vous limitez le nombre de tâches exécutées, mais vous ne limitez pas le nombre de tâches qui peuvent être soumises et mises en file d'attente pour une exécution ultérieure. L'application connaîtra une pénurie de ressources plus tard, mais elle finira par la connaître si le taux de soumission dépasse systématiquement le taux d'exécution.
La solution à ce problème est : Fournir une file d'attente bloquante à l'exécuteur pour contenir les tâches en attente. Si la file d'attente se remplit, la tâche soumise sera "rejetée". Le site RejectedExecutionHandler
est invoqué lorsqu'une soumission de tâche est rejetée, et c'est pourquoi le verbe rejected a été cité dans l'article précédent. Vous pouvez implémenter votre propre politique de rejet ou utiliser l'une des politiques intégrées fournies par le framework.
Les politiques de rejet par défaut font que l'exécuteur lance un message d'erreur RejectedExecutionException
. Cependant, d'autres politiques intégrées vous permettent :
- Rejeter un travail en silence.
- Jetez le travail le plus ancien et essayez de soumettre à nouveau le dernier.
- Exécuter la tâche rejetée sur le thread de l'appelant.
- Réponses précédentes
- Plus de réponses