我写了一个简单的工具,它检查一些xml(解组和内容分析)的内容,并为每个xml编写一个日志文件。
我必须检查大约 2 MB/文件的一千多个文件。所以进展需要一些时间。因为我的文件之间没有依赖关系,所以我尝试在不同的线程中完成工作(没有同步方法)。
不幸的是,我的遗嘱执行器服务似乎出了问题。我尝试使用固定线程池执行器服务。但是具有 1 个和 100 个线程的运行时几乎不同(以及 CPU 使用率)。只有当我每个文件使用 1 个线程 (files.size) 时,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();
}
}
}
我认为没有关系或不容易的关系。这取决于线程正在执行的工作。具有一个线程的程序可以消耗 100% 的 CPU,而具有大量线程的程序可以消耗更少的 CPU。
如果您正在寻找线程和完成作业之间的优化关系,则必须研究您的案例,并可能找到经验解决方案。
感谢您的回复。
正如@hagrawal所写,使用 1、10 或 100 个线程之间没有区别。如果我使用的线程与列表中的文件一样多,我的 CPU 使用率就会高得多(直到 CPU 成为瓶颈),并且整个进度需要大约 10% 的时间。不幸的是,这需要大量的内存,我担心它会导致将来有更多文件的软件崩溃。
我无法想象,这可能是I/O问题。我的机器的 raid 0 系统应该能够毫不费力地做到这一点。如果我对问题的理解是正确的,它就不可能是 I/O 问题。因为如果 I/O 是瓶颈,那么如果线程数等于文件数(在我的例子中约为 1000),性能应该不会增加。还是我的薄荷有问题?
不幸的是,CPU 使用率与 1、10 和 100 个线程几乎不同。所以我的印象是,进度从固定数量的线程(如配置)开始,执行器服务在启动新线程之前等待所有线程终止。但我的理解是,一旦第一个线程终止并免费,它就会启动一个新线程?