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.