2017-05-24 24 views
0

我写了一个简单的工具,它检查内容的一些xml(解组和内容分析),并为每个xml写入一个日志文件。FixedThreadPool线程数和运行时间

我必须检查超过几千个文件,大约2 MB /文件。所以进展需要一些时间。因为我的文件之间没有依赖关系,所以我尝试在不同的线程中完成这项工作(没有同步的方法)。

不幸的是,我的ExecutorService的东西似乎是错的。我试图使用一个fixedthreadpool Executorservice。但是具有1和100线程的运行时间几乎是一样的(以及CPU使用率)。只有在每个文件(files.size)使用1个线程的情况下,CPU使用率要高得多(大约90%),运行时间大约是原始运行时间的10%。

我不明白为什么1线程的运行时和CPU使用率与100线程相同。

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

当您将'max.threadcount'指定为1并且将其指定为100时,您无法找到区别吗?你可以提供一个最小可重复的代码,因为看这段代码我认为你应该得到X个并行处理线程,其中X ='max.threadcount'。 – hagrawal

+1

当您仅使用一个线程运行时,该进程花费了多少时间进行计算以及花费了多少时间来执行I/O?您的计算机可能具有多个CPU,因此添加更多的线程可以使其计算速度更快(达到您拥有的CPU数量),但是如果所有这些文件都在同一个磁盘上......只有一个端口用于与磁盘交谈。添加更多的线程根本不会改善I/O时间。 –

回答

0

我觉得没有关系或不容易。这取决于线程正在做的工作。具有一个线程的程序可以占用100%的CPU,而具有大量线程的程序可以消耗更少的CPU。

如果您正在寻找线程与完成工作之间的优化关系,则必须研究您的情况,并可能找到经验丰富的解决方案。

0

感谢您的回复。

正如@hagrawal写道,使用1,10或100个线程没有区别。就像我使用尽可能多的线程,因为我的列表上有文件,我的CPU使用率就会更高(直到CPU成为瓶颈),整个过程需要大约10%的时间。不幸的是,这需要大量的内存,我担心,它将在未来导致更多文件的软件崩溃。

我无法想象,它可能是一个I/O问题。我的机器的raid 0系统应该可以毫不费力地做到这一点。如果我对这个问题的理解是正确的,那么它就不是I/O问题。因为如果I/O是瓶颈,如果线程数等于文件数(在我的情况下大约为1000),性能不应该增加。或者我的薄荷有什么不对?

不幸的是,CPU使用率与1,10和100线程几乎完全相同。所以我的印象是,进程从固定数量的线程开始(如配置)并且执行程序服务等待它们全部终止,然后再启动一个新线程。但我的理解是,只要第一个终止并释放,它就开始一个新线程?