【发布时间】:2017-03-21 17:46:12
【问题描述】:
有几个问题,例如here 或here,询问为什么额外的线程会降低性能。我明白了。
我有一个有点相反的问题:一个额外的线程如何才能将性能提高一倍? 10个甚至20个?
示例代码:
public class MainThreaded {
public static void main(String[]
String filePath = "my\\path\\";
String[] inFiles = {filePath+"file1.txt",filePath+"file2.txt"};
String[] outFiles = {filePath + "file1Out.txt", filePath + "file2Out.txt"};
long startTime = System.currentTimeMillis();
for (int i = 0; i < inFiles.length; i++) {
Adder adder = new Adder(inFiles[i], outFiles[i]);
// adder.doAdd();
Thread thread = new Thread(adder);
thread.start();
}
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("That took " + totalTime+ " milliseconds");
}
}
public class MainNoThread {
public static void main(String[] args) {
String filePath = "my\\path\\";
String[] inFiles = {filePath+"file1.txt",filePath+"file2.txt"};
String[] outFiles = {filePath + "file1Out.txt", filePath + "file2Out.txt"};
long startTime = System.currentTimeMillis();
for (int i = 0; i < inFiles.length; i++) {
Adder adder = new Adder(inFiles[i], outFiles[i]);
try {
adder.doAdd();
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
System.out.println("That took " + totalTime+ " milliseconds");
}
}
public class Adder implements Runnable {
private String inFile, outFile;
public Adder(String inFile, String outFile){
this.inFile = inFile;
this.outFile = outFile;
}
public void doAdd() throws IOException{
int lines = 0;
try(BufferedReader reader = Files.newBufferedReader(Paths.get(inFile))){
while (reader.readLine() != null) {
lines++;
}
try(BufferedWriter writer = Files.newBufferedWriter(Paths.get(outFile))){
writer.write("Total: " + lines);
}
}
}
@Override
public void run() {
try {
doAdd();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 第一个没有线程的应用程序需要大约。 40 毫秒
- 第二个版本,只创建一个额外的
new Thread()需要 2 毫秒。
所以我的问题是:如此大幅度的改进背后的原因是什么?
【问题讨论】:
-
您确定要等待线程完成吗?可以出示一下代码吗?
-
你考虑过磁盘缓存吗?
-
你是如何实现第二个版本的?如果没有看到这两个代码,很难判断会发生什么。也许你先运行单线程,当第二个运行时,文件已经在系统的文件系统缓存中?
-
拙劣的基准测试会给出各种奇怪的结果。
-
@Andrey,但是在您的完整代码中,您只是启动线程,您没有测量在 doAdd() 中执行实际工作所需的时间。或者更确切地说,您无需等待任何线程完成,您只需启动它们,然后打印出启动线程所需的时间。
标签: java multithreading concurrency