Pools de threads personnalisés pour les flux parallèles Java 8
Dans le domaine des flux parallèles Java 8, la question se pose : est-il possible d'employer des pools de threads personnalisés pour des tâches spécifiques ? Malgré des recherches approfondies, cette fonctionnalité a échappé à de nombreux développeurs.
Prenons l'exemple d'une application serveur multithread dans laquelle des flux parallèles sont souhaités. Cependant, pour maintenir la compartimentation et empêcher les tâches d'un module d'en bloquer les autres, différents pools de threads sont nécessaires pour chaque module.
Pour illustrer le problème, considérons l'exemple suivant :
ExecutorService es = Executors.newCachedThreadPool(); es.execute(() -> runTask(1000)); // incorrect task es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0)); es.execute(() -> runTask(0));
Dans ce cas Dans cet exemple artificiel, les tâches gourmandes en CPU sont exécutées en parallèle à l'aide de Executors.newCachedThreadPool(). La première tâche est délibérément ralentie par la mise en veille simulée des threads. En conséquence, d’autres tâches restent bloquées, en attente d’achèvement. Cela démontre comment une tâche lente dans un module peut gêner les tâches dans d'autres modules.
Cependant, il existe une solution intelligente à ce dilemme : exécuter des opérations parallèles en tant que tâches au sein d'un pool de jointure fork spécifique. Ce faisant, ils restent isolés du pool commun de jointure fork utilisé par d'autres opérations de flux parallèles.
final int parallelism = 4; ForkJoinPool forkJoinPool = null; try { forkJoinPool = new ForkJoinPool(parallelism); final List<Integer> primes = forkJoinPool.submit(() -> // Parallel task here, for example IntStream.range(1, 1_000_000).parallel() .filter(PrimesPrint::isPrime) .boxed().collect(Collectors.toList()) ).get(); System.out.println(primes); } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } finally { if (forkJoinPool != null) { forkJoinPool.shutdown(); } }
Cette technique exploite ForkJoinTask.fork(), qui spécifie que si la tâche actuelle s'exécute dans un pool fork-join, l’exécution asynchrone doit avoir lieu dans ce pool. Sinon, ForkJoinPool.commonPool() sera utilisé.
En utilisant cette approche, vous pouvez utiliser en toute sécurité des flux parallèles dans divers modules au sein d'une application multithread sans compromettre les performances ou la compartimentation des tâches.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!