Quelle est exactement la différence entre la taille du pool de base et la taille maximale du pool lorsque nous parlons de ThreadPoolExecutor
?
Peut-on l'expliquer à l'aide d'un exemple?
java
asynchronous
threadpoolexecutor
user2568266
la source
la source
Réponses:
De cet article de blog :
la source
allowCoreThreadTimeOut(boolean)
qui permet de tuer les threads principaux après un temps d'inactivité donné. Définir ceci sur true et définircore threads
=max threads
permet au pool de threads de s'échelonner entre 0 etmax threads
.Si vous exécutez des threads> corePoolSize & <maxPoolSize , créez un nouveau thread si la file d'attente de tâches Total est pleine et qu'une nouvelle arrive.
Form doc: (S'il y a plus de threads corePoolSize mais moins que maximumPoolSize en cours d'exécution, un nouveau thread sera créé uniquement si la file d'attente est pleine.)
Maintenant, prenons un exemple simple,
Ici, 5 est le corePoolSize - signifie que Jvm créera un nouveau thread pour une nouvelle tâche pour les 5 premières tâches. et d'autres tâches seront ajoutées à la file d'attente jusqu'à ce que la file d'attente soit pleine (50 tâches).
10 est le maxPoolSize - JVM peut créer un maximum de 10 threads. 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 supplémentaire arrive dans la file d'attente, JVM créera un nouveau thread jusqu'à 10 (nombre total de threads = 5 précédents + nouveau 5) ;
new ArrayBlockingQueue (50) = est une taille totale de file d'attente - il peut y mettre 50 tâches en file d'attente.
une fois que les 10 threads sont en cours d'exécution et si une nouvelle tâche arrive, cette nouvelle tâche sera rejetée.
Règles de création de threads en interne par SUN:
Si le nombre de threads est inférieur à corePoolSize, créez un nouveau Thread pour exécuter une nouvelle tâche.
Si le nombre de threads est égal (ou supérieur) à corePoolSize, placez la tâche dans la file d'attente.
Si la file d'attente est pleine et que le nombre de threads est inférieur à 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, rejetez la tâche.
J'espère que c'est utile ... et s'il vous plaît, corrigez-moi si je me trompe ...
la source
Du doc :
En outre:
la source
Si vous décidez de créer un
ThreadPoolExecutor
manuellement au lieu d'utiliser laExecutors
classe de fabrique, vous devrez en créer et en configurer un à l'aide de l'un de ses constructeurs. Le constructeur le plus étendu de cette classe est:Comme vous pouvez le voir, vous pouvez configurer:
Limitation du nombre de tâches en file d'attente
Limiter le nombre de tâches simultanées en cours d'exécution, dimensionner votre pool de threads, représente un énorme avantage pour votre application et son environnement d'exécution en termes de prévisibilité et de stabilité: une création de thread illimitée finira par épuiser les ressources d'exécution et votre application pourrait en subir les conséquences. , de graves problèmes de performances pouvant même entraîner une instabilité de l'application.
C'est une solution à une seule partie du problème: vous limitez le nombre de tâches en cours d'exécution mais ne limitez pas le nombre de travaux qui peuvent être soumis et mis 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 en souffrir 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 de blocage à l'exécuteur pour contenir les tâches en attente. Dans le cas où la file d'attente se remplit, la tâche soumise sera "rejetée". Le
RejectedExecutionHandler
est appelé lorsqu'une soumission de tâche est rejetée, et c'est pourquoi le verbe rejeté a été cité dans l'élément précédent. Vous pouvez mettre en œuvre votre propre politique de rejet ou utiliser l'une des politiques intégrées fournies par l'infrastructure.Les politiques de rejet par défaut obligent l'exécuteur à lancer un
RejectedExecutionException
. Cependant, d'autres stratégies intégrées vous permettent:la source
La source
Les règles relatives à la taille d'une
ThreadPoolExecutor's
piscine sont généralement mal comprises, car cela ne fonctionne pas comme vous le pensez ou comme vous le souhaitez.Prenons cet exemple. La taille du pool de threads de départ est 1, la taille du pool principal est de 5, la taille maximale du pool est de 10 et la file d'attente est de 100.
La manière de Sun: au fur et à mesure que les requêtes arrivent, les threads seront créés jusqu'à 5, puis 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 seront créés jusqu'à
maxPoolSize
. Une fois que tous les threads sont utilisés et que la file d'attente est pleine, les tâches seront rejetées. À mesure que la file d'attente diminue, le nombre de threads actifs diminue également.Manière prévue par l'utilisateur: au fur et à mesure que les demandes arrivent, les threads seront créés jusqu'à 10, puis les tâches seront ajoutées à la file d'attente jusqu'à ce qu'elle atteigne 100, point auquel elles sont 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 mourront jusqu'à ce qu'il en
corePoolSize
reste.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 la taille du pool petite et ne l'augmenter que lorsque la charge devient trop importante.
Voici les règles de Sun pour la création de threads en termes simples:
corePoolSize
, créez un nouveau thread pour exécuter une nouvelle tâche.corePoolSize
, placez la tâche dans la file d'attente.maxPoolSize
, créez un nouveau thread pour exécuter les tâches.maxPoolSize
, rejetez la tâche. Le long et court est que de nouveaux threads ne sont créés que lorsque la file d'attente se remplit, donc si vous utilisez une file d'attente illimitée, le nombre de threads ne dépassera pascorePoolSize
.Pour une explication plus complète, obtenez-le de la bouche du cheval:
ThreadPoolExecutor
documentation de l'API.Il y a un très bon message sur le forum qui vous explique comment cela
ThreadPoolExecutor
fonctionne avec des exemples de code: http://forums.sun.com/thread.jspa?threadID=5401400&tstart=0Plus d'infos: http://forums.sun.com/thread.jspa?threadID=5224557&tstart=450
la source
Vous pouvez trouver la définition des termes corepoolsize et maxpoolsize dans le javadoc. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Le lien ci-dessus a la réponse à votre question. Cependant, juste pour que ce soit clair. L'application continuera à créer des threads jusqu'à ce qu'elle atteigne corePoolSize. Je pense que l'idée ici est que ces nombreux threads devraient être suffisants pour gérer l'afflux de tâches. Si une nouvelle tâche survient après la création des threads corePoolSize, les tâches seront mises en file d'attente. Une fois la file d'attente pleine, l'exécuteur commencera à créer de nouveaux threads. C'est une sorte d'équilibre. Cela signifie essentiellement que l'afflux de tâches est supérieur à la capacité de traitement. Ainsi, Executor recommencera à créer de nouveaux threads jusqu'à ce qu'il atteigne le nombre maximum de threads. Encore une fois, un nouveau thread sera créé si et seulement si la file d'attente est pleine.
la source
Bonne explication dans ce blog:
Illustration
Production :
la source
Extrait du livre Java concurency essentials :
CorePoolSize : Le ThreadPoolExecutor a un attribut corePoolSize qui détermine le nombre de threads qu'il démarrera jusqu'à ce que les nouveaux threads ne soient démarrés que lorsque la file d'attente est pleine
MaximumPoolSize : cet attribut détermine combien de threads sont démarrés au maximum. Vous pouvez le définir sur Integer. MAX_VALUE pour ne pas avoir de limite supérieure
la source
java.util.concurrent.ThreadPoolExecutor
la source
Comprendre le comportement interne du
ThreadPoolExecutor
lorsqu'une nouvelle tâche est soumise m'a aidé à comprendre commentcorePoolSize
etmaximumPoolSize
différer.Laisser:
N
le nombre de fils dans la piscine,getPoolSize()
. Threads actifs + threads inactifs.T
être la quantité de tâches soumises à l'exécuteur / pool.C
la taille du pool de base,getCorePoolSize()
. Combien de threads au maximum peuvent être créés par pool pour les tâches entrantes avant que les nouvelles tâches ne soient placées dans la file d'attente .M
la taille de la piscine maximale,getMaximumPoolSize()
. Nombre maximum de threads que le pool peut allouer.Comportements de
ThreadPoolExecutor
en Java lorsqu'une nouvelle tâche est soumise:N <= C
, les threads inactifs ne reçoivent pas la nouvelle tâche entrante, mais un nouveau thread est créé.N > C
et s'il y a des threads inactifs, une nouvelle tâche y est affectée.N > C
et s'il n'y a AUCUN thread inactif, de nouvelles tâches sont placées dans la file d'attente. AUCUN NOUVEAU FIL CRÉÉ ICI.M
. SiM
est atteint, nous rejetons les tâches. Ce qui est important de ne pas ici, c'est que nous ne créons pas de nouveaux threads tant que la file d'attente n'est pas pleine!Sources:
Exemples
Exemple avec
corePoolSize = 0
etmaximumPoolSize = 10
avec une capacité de file d'attente de50
.Cela se traduira par un seul thread actif dans le pool jusqu'à ce que la file d'attente contienne 50 éléments.
Exemple avec
corePoolSize = 10
etmaximumPoolSize = 10
avec une capacité de file d'attente de50
.Cela entraînera 10 threads actifs dans le pool. Lorsque la file d'attente contient 50 éléments, les tâches sont rejetées.
la source