2017-05-24 1 views
0

J'ai écrit un outil simple qui vérifie certains xml (unmarshalling et analyses de contenu) pour le contenu et écrit un fichier journal par xml.FixedThreadPool threadcount et runtime

Je dois vérifier plus de mille fichiers avec environ 2 Mo/fichier. Donc, le progrès prend du temps. Parce qu'il n'y a pas de dépendances entre mes fichiers, j'ai essayé de faire le travail dans différents threads (pas de méthodes synchronisées).

Malheureusement quelque chose avec mon ExecutorService semble être faux. J'ai essayé d'utiliser un Executorservice fixedthreadpool. Mais l'exécution avec 1 et 100 threads est à peine la même (ainsi que l'utilisation du processeur). Seulement si j'utilise 1 Thread par fichier (files.size) l'utilisation du processeur est beaucoup plus élevée (environ 90%) et le temps d'exécution est d'environ 10% de l'exécution d'origine.

Je ne comprends pas pourquoi l'utilisation de runtime et cpu avec 1 thread est la même qu'avec 100 threads.

package mycode; 

import java.io.BufferedWriter; 
import java.io.File; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class Starter { 

public static void main(String[] args) { 
    File config = new File(args[0]); 
    Starter starter = new Starter(); 
    starter.work(config); 
} 

private void work(File config) 
{ 
    Long start = System.currentTimeMillis(); 
    ConfigReader cr = new ConfigReader(config); 
    cr.init(); 
    FileFinder ff = new FileFinder(); 
    List<File>files = ff.findfiles(cr.getParam("xmlfolder")); 
    List<String>done = new ArrayList<String>(); 


    ExecutorService es = Executors.newFixedThreadPool(Integer.parseInt(cr.getParam("max.threadcount"))); 
    for (File aktuell : files) 
    { 
     es.execute(new Threadstarter(aktuell, cr.getParam("logoutput"), done)); 
    } 



    es.shutdown(); 


    try { 
     es.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES); 

    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    Long end = System.currentTimeMillis(); 
    BufferedWriter logwriter; 
    try { 
     logwriter = new BufferedWriter(new FileWriter(new File(cr.getParam("logoutput")).getAbsolutePath()+"/log.log")); 
     for (String temp : done) 
     { 
      logwriter.write(temp); 
      logwriter.newLine(); 
     } 
     logwriter.write("Die Verarbeitung dauerte "+(end-start)/1000 +" Sekunden"); 
     logwriter.newLine(); 
     logwriter.write("Es wurden "+files.size()+" Dienststellen verarbeitet"); 
     logwriter.flush(); 
     logwriter.close(); 
    } catch (IOException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 


} 

} 
+0

Vous ne pouvez pas trouver de différence lorsque vous spécifiez 'max.threadcount' comme 1 et lorsque vous spécifiez cela comme 100? Et pouvez-vous fournir un code minimal reproductible parce qu'en regardant ce code, je pense que vous devriez obtenir X nombre de threads de traitement en parallèle où X = 'max.threadcount'. – hagrawal

+1

Lorsque vous exécutez avec un seul thread, combien de temps le processus passe-t-il à faire du calcul et combien de temps consacre-t-il à faire des E/S? Votre ordinateur a probablement plus d'un processeur, donc ajouter plus de threads lui permet de calculer plus rapidement (jusqu'au nombre de CPU que vous avez), mais si tous ces fichiers sont sur le même disque ... Il n'y a qu'un seul port pour parler au disque. Ajouter plus de threads n'améliorera en rien le temps d'E/S. –

Répondre

0

Je pense qu'il n'y a aucune relation ou pas facile. Cela dépend des tâches que les threads font. Un programme avec un thread peut consommer 100% du CPU et un programme avec beaucoup de threads peut consommer moins.

Si vous recherchez une relation optimisée entre les threads et le travail effectué, vous devez étudier votre cas et éventuellement trouver une solution empirique.

0

Nous vous remercions de vos réponses. Comme l'a écrit @hagrawal, il n'y a pas de différence entre travailler avec 1, 10 ou 100 threads. Juste si j'utilise autant de threads que j'ai de fichiers sur ma liste, j'ai beaucoup plus d'utilisation du CPU (jusqu'à ce que le CPU devienne le goulot d'étranglement) et tout le processus nécessite environ 10% de temps. Malheureusement, cela nécessite une énorme quantité de mémoire et j'ai peur que cela ne provoque un crash logiciel avec encore plus de fichiers à l'avenir.

Je ne peux pas imaginer que cela pourrait être un problème d'E/S. Le système RAID 0 de ma machine devrait être capable de le faire sans effort. Si ma compréhension du problème est correcte, cela ne peut pas être un problème d'E/S. Parce que si l'E/S est le goulot d'étranglement, la performance ne devrait pas augmenter si le nombre de threads est égal au nombre de fichiers (dans mon cas environ 1000). Ou y a-t-il quelque chose qui ne va pas dans ma monnaie?

Malheureusement, l'utilisation du processeur est à peine identique avec 1, 10 et 100 threads. Donc, mon impression est que la progression commence avec un nombre fixe de threads (comme configuré) et le service d'exécution attend que tous les threads soient terminés, avant qu'il n'en commence un nouveau. Mais ma compréhension était, que cela commence un nouveau fil, dès que le premier est terminé et libre?