167 votes

Taille du pool principal par rapport à la taille maximale du pool dans ThreadPoolExecutor

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 ?

177voto

user2568266 Points 3323

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.

95voto

Darshan Dalwadi Points 438

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 :

  1. Si le nombre de threads est inférieur au corePoolSize, créez un nouveau Thread pour exécuter une nouvelle tâche.

  2. Si le nombre de threads est égal (ou supérieur) au corePoolSize, la tâche est placée dans la file d'attente.

  3. 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.

  4. 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...

26voto

premraj Points 120

Source :

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 :

  1. 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.
  2. 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.
  3. 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.
  4. 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 suivantes corePoolSize .

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

21voto

Brian Agnew Points 143181

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).

10voto

Prashant Gautam Points 529

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X