2017-06-18 1 views
-1

Comment traiter un nombre potentiellement énorme d'éléments de liste en utilisant un nombre fixe de threads? J'ai une solution à l'aide ExecutorService:Traitement d'éléments de liste avec un nombre fixe de threads

 ExecutorService threadPool = 
     Executors.newFixedThreadPool(threadsNumber); 
     for (String url : urlList) { 
      MyThread thread = new MyThread(url); 
      threadPool.execute(thread); 
     } 
     threadPool.shutdown(); 
     threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 

Ce code me renvoie le résultat correct, mais au lieu de créer un nouveau thread à chaque itération je voudrais créer un certain nombre de threads avant l'itération et de les réutiliser. Comment puis-je faire ceci?

+0

Pas votre question. Je ne vois aucune différence, soit vous créez un fil à l'extérieur ou à l'intérieur de la boucle. Pourquoi pensez-vous que cela fera la différence? – Ravi

+0

La création de threads à l'intérieur d'une boucle dépend du nombre d'éléments dans la liste d'itération. Si la liste contient un grand nombre d'éléments, vous devrez créer beaucoup de threads. Je voudrais l'éviter en créant des threads avant qu'une boucle ne soit affectée par un certain nombre d'éléments dans 'urlList' – MoBi

+0

Il ne créera que le nombre de thread, qui est spécifié – Ravi

Répondre

0

Qu'est-ce que MyThread? Est-ce que cela s'étend Thread? Le but d'un Executor est de créer et gérer des discussions pour vous. Vous ne devriez pas créer vos propres discussions si vous utilisez un ExecutorService. Ils seront simplement traités comme Runnable s, et le ExecutorService les exécutera en utilisant son propre pool de threads.

+0

Concernant MyThread - oui, c'est le cas. Il n'est pas obligatoire d'utiliser 'Executor'. Je veux trouver une solution équivalente sans créer beaucoup de threads à cause de la consommation de mémoire. – MoBi

+0

La solution n'est pas d'étendre 'Thread'. Il suffit d'étendre 'Runnable'. Le 'Executor' que vous avez déjà créé s'occupera de répartir les tâches entre les threads. – Sam

+0

Cela a du sens. Je vous remercie! – MoBi

0

Si vous ne voulez pas trop d'opérations new(), réutilisez la tâche comme suit.

public class MyRunable implements Runnable { 
    private String param; 
    public void setParam(String param) { 
     this.param = param; 
    } 

    public void run() { 
      System.out.println("param: "+param + " in thread:" + Thread.currentThread().getName()); 
    } 
} 

public class Test { 
    private ExecutorService executor; 

    public Test(int threadNum) { 
     executor = Executors.newFixedThreadPool(threadNum); 
    } 

    public Future<?> submitTask(MyRunable task) { 
     Future<?> f = executor.submit(task); 
     return f; 
    } 

    public static void main(String args[]) { 
     Test test = new Test(2); 
     MyRunable task1 = new MyRunable(); 
     MyRunable task2 = new MyRunable(); 

     List<String> urls = new ArrayList<String>(); 
     urls.add("URL1"); 
     urls.add("URL2"); 
     urls.add("URL3"); 
     urls.add("URL4"); 

     try { 
      for (int i = 0; i< urls.size(); i+=2) { 
       task1.setParam(urls.get(i)); 
       task2.setParam(urls.get(i+1)); 
       Future f1 = test.submitTask(task1); 
       Future f2 = test.submitTask(task2); 
       f1.get(); 
       f2.get(); 
      } 
     } catch (Exception e) {} 
    } 
}