2016-08-26 2 views
0

Je suis en train de tester l'avenir. Comme décrit here je pensais fil serait réutilisée de la piscine commune, mais cet extrait montre un comportement étrangeCompletableFuture réutiliser le fil de la piscine

for (int i = 0; i < 10000; i++) { 
      final int counter = i; 
      CompletableFuture.supplyAsync(() -> { 

       System.out.println("Looking up " + counter + " on thread " + Thread.currentThread().getName()); 
       return null; 
      }); 
} 

Je ce genre de sortie:

Looking up 0 on thread Thread-2 
Looking up 1 on thread Thread-3 
Looking up 2 on thread Thread-4 
... 
Looking up 10000 on thread Thread-10002 

il ressemble à un nouveau thread est créé pour chaque tâche. Pourquoi tout mon achèvementableFuture ne réutilise pas le thread du pool commun?

Je l'ai testé plus avec RxJava et il fonctionne comme excpected avec ce code:

for (int i = 0; i < 10000; i++) { 
      rxJobExecute(i).subscribeOn(Schedulers.io()).subscribe(); 
     } 

private Observable<String> rxJobExecute(int i) { 
     return Observable.fromCallable(() -> { 

      System.out.println("emission " + i + " on thread " + Thread.currentThread().getName()); 
      return "tata"; 

     }); 
    } 

sortie

emission 8212 on thread RxIoScheduler-120 
emission 8214 on thread RxIoScheduler-120 
emission 8216 on thread RxIoScheduler-120 
emission 8218 on thread RxIoScheduler-120 
emission 8220 on thread RxIoScheduler-120 
emission 7983 on thread RxIoScheduler-275 
emission 1954 on thread RxIoScheduler-261 
emission 1833 on thread RxIoScheduler-449 
emission 1890 on thread RxIoScheduler-227 
+0

Combien de processeurs avez-vous sur votre machine? –

+0

Salut, j'ai 2 processeurs – bodtx

Répondre

1

Les chances sont que, puisque vous avez seulement 2 processeurs alors la valeur Runtime.getRuntime().availableProcessors() au démarrage de l'application seulement observé processeur 1 (le avialableProcessors retournera tout nombre entre 1 et le nombre de processeurs sur votre machine et n'est pas tout à fait déterministe).

La piscine commune ForkJoin utilisera un thread par tâche pool de threads si le parallélisme est 1.

Pour forcer le système à charger avec un parallélisme particulier (pour ce au moins) définir la propriété système -Djava.util.concurrent.ForkJoinPool.common.parallelism=2 comme un argument d'exécution

Edit:

je regardais à nouveau la logique interne. Puisque vous avez 2 cœurs, le parallélisme sera toujours d'utiliser le fil par tâche. La logique attend supérieure ou égale à 3, vous devrez donc mettre à jour le parallélisme à 3

-Djava.util.concurrent.ForkJoinPool.common.parallelism=3.

L'alternative est de définir votre propre ThreadPool

+0

en effet avec cela dans le code System.setProperty ("java.util.concurrent.ForkJoinPool.common.parallelism", "3") ;, Je n'ai que 3 threads utilisés sur mon ordinateur 2 cpu – bodtx