3 votes

ThreadPoolExecutor - Puis-je jeter une exception si le pool est plein

Est-il possible de lancer une exception si la demande entrante ne peut pas être traitée?

Donc, j'ai un pool de threads fixe :

private val executor: ThreadPoolExecutor = Executors.newFixedThreadPool(4) as ThreadPoolExecutor

Et je ne veux pas que les demandes aillent dans la file d'attente des threads si elles ne peuvent pas être traitées, je veux simplement lancer une exception.

J'essaie de vérifier le activeCount et de lancer une exception si celui-ci est supérieur à la taille maximale du pool, mais cela ne fonctionne pas comme je le souhaite.

private fun checkPoolSize() {
    if (executor.activeCount >= 4) {
        throw RuntimeException("La demande ne peut pas être traitée. ")
    }
}

4voto

Alexandre Dupriez Points 711

Une solution pour cela est d'utiliser une file d'attente de capacité 0 et java.util.concurrent.ThreadPoolExecutor.AbortPolicy en tant que RejectedExecutionHandler.

Les méthodes statiques dans Executors ne exposent pas l'ensemble complet de paramètres que vous souhaitez pour cela, donc vous devrez instancier directement un ThreadPoolExecutor. Dans votre cas, vous pourriez utiliser ce qui suit :

new ThreadPoolExecutor(4,                                     /* Taille du pool principal          */
                       4,                                     /* Taille maximale du pool           */
                       0, TimeUnit.SECONDS,                   /* Durée du pool principal           */
                       new MyQueue(0),              /* Aucune mise en file d'attente     */
                       Executors.defaultThreadFactory(),      /* par défaut                        */
                       new AbortPolicy())                     /* jette une exception lorsque tous les threads principaux sont occupés */

Quelques notes :

  • 0 secondes (3ème et 4ème arguments) correspondent à la durée du pool principal. Mettre 0 signifie que vos threads principaux ne seront jamais arrêtés même s'ils restent inactifs. C'est le comportement par défaut lors de l'utilisation de Executors.newFixedThreadPool(4).
  • Executors.defaultThreadFactory() est la fabrique de threads par défaut, similaire à celle utilisée avec Executors.newFixedThreadPool(4).
  • Ici, la taille du pool principal et du pool maximum est définie à 4 (1er et 2ème argument), ce qui semble approprié pour votre cas d'utilisation.
  • MyQueue est une implémentation de BlockingQueue qui accepte 0 en tant que capacité (c'est-à-dire qui ne peut être que vide. Ce n'est bien sûr pas une file d'attente mais en l'implémentant cela permet une intégration transparente avec le ThreadPoolExecutor fourni par le JDK.).

Autre considération:

Avec un tel réglage fin de votre pool de threads, méfiez-vous que le débit sera limité. Ici, en considérant 4 threads et une latence moyenne L en secondes pour les tâches soumises au pool de threads, le débit moyen autorisé par cette configuration est de 4/L tâches/seconde.

1 votes

Il s'agit de la solution que je recherche, mais je dois créer ma propre implémentation de BlockingQueue car LinkedBlockingQueue lance une IllegalArgumentException si l'argument de capacité est <= 0.

0 votes

@DamianU Ah d'accord, désolé je pensais que cela serait accepté.

1 votes

@DamianU vous n'avez pas besoin de mettre en œuvre votre propre file d'attente, SynchronousQueue est ce que vous cherchez.

2voto

Saptarshi Basu Points 1231

Vous pouvez utiliser une politique de saturation qui entre en jeu lorsque votre file d'attente bornée se remplit. Vous pouvez définir une politique de saturation en appelant setRejectedExecutionHandler() de ThreadPoolExecutor. Les implémentations prêtes à l'emploi sont AbortPolicy, CallerRunsPolicy, DiscardPolicy et DiscardOldestPolicy. AbortPolicy est par défaut et lance une RejectedExecutionException lorsque la file d'attente bornée est pleine. Vous pouvez également fournir votre propre implémentation personnalisée.

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