La sagesse conventionnelle nous dit que les applications java d'entreprise à fort volume doivent utiliser le pooling de threads plutôt que de créer de nouveaux threads de travail. L'utilisation de java.util.concurrent
permet de simplifier les choses.
Il existe cependant des situations où le pooling de threads n'est pas une bonne solution. L'exemple spécifique avec lequel je me bats actuellement est l'utilisation de InheritableThreadLocal
qui permet ThreadLocal
pour qu'elles soient "transmises" à tous les threads créés. Ce mécanisme ne fonctionne pas lorsqu'on utilise des pools de threads, car les threads de travail ne sont généralement pas créés à partir du thread de la requête, mais sont préexistants.
Il existe des moyens de contourner ce problème (les locals du fil peuvent être explicitement transmis), mais ce n'est pas toujours approprié ou pratique. La solution la plus simple est de créer de nouveaux threads de travail à la demande, et de laisser InheritableThreadLocal
faire son travail.
Cela nous ramène à la question suivante : si j'ai un site à fort volume, où les threads de requête des utilisateurs génèrent chacun une demi-douzaine de threads de travail (c'est-à-dire sans utiliser de pool de threads), cela va-t-il poser un problème à la JVM ? Nous parlons potentiellement de quelques centaines de nouveaux threads créés chaque seconde, chacun durant moins d'une seconde. Les JVM modernes optimisent-elles bien cela ? Je me souviens de l'époque où la mise en commun des objets était souhaitable en Java, car la création d'objets était coûteuse. Depuis, cela est devenu inutile. Je me demande s'il en va de même pour le pooling de threads.
Je l'évaluerais bien, si je savais ce qu'il faut mesurer, mais je crains que les problèmes soient plus subtils que ce que l'on peut mesurer avec un profileur.
Remarque : le bien-fondé de l'utilisation des localisateurs de fil n'est pas la question ici, alors ne me suggérez pas de ne pas les utiliser.