[英]Write to multiple text files from multiple threads
我正在做一些关于多线程的实验。
当程序运行到输出部分时(使用java.io.FileWriter
),有时可以快速通过,但有时只是停留在该位置。
是FileWriter
的问题吗? 这是简化的代码:
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Test extends Thread {
private int _id;
public Test(int id) {
_id = id;
}
@Override
public void run() {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
try (FileWriter fw = new FileWriter(new File(_id + ".txt"))) {
fw.write("hello!");
} catch (IOException e) {
System.err.println("Something wrong.");
}
}
System.out.println(_id + ": " + (System.currentTimeMillis() - start));
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Test(i).start();
}
}
}
这是我的结果:
7: 3820 9: 3878 2: 3965 8: 3956 0: 4058 6: 4097 5: 4111 3: 4259 1: 4354 4: 4369
9: 4703 7: 4748 5: 4891 2: 4994 4: 5065 3: 5672 1: 5804 0: 5805 8: 5925 6: 6042
1: 4495 9: 5265 6: 5551 2: 5651 5: 5676 8: 5697 3: 5917 0: 6001 7: 6002 4: 6314
我运行了3次,为什么经过的时间不同? 是FileWriter
的问题还是文件系统的问题?
您至少有两个问题:
open()
, write()
((可能是flush()
,最后是close()
;至少300k syscalls! FileWriter
对象,100k File
对象; gc需要处理所有这些问题; 由于gc本身在线程中运行,并且像其他线程一样进行调度,因此它将或多或少地运行。 因此,问题出在您的程序上,而不是与操作系统相关的任何事情……JIT在这里无法为您做任何事情。
另外,由于使用Java 7,因此应考虑使用Files.newBufferedWriter()
-每个线程仅使用一次,当然,不要使用10000次!
关于“系统调用问题”的进一步说明:至少在Unix系统上,但是其他操作系统可能工作相同, 每次执行系统调用时,您的进程都必须在执行系统调用时进入内核模式; 这不是免费的。 即使在现代系统的成本是不是显著,但它仍然是比没有做用户>内核级>用户显著较高。
好吧,我撒了一点谎。 JIT确实可以实现,但只会优化用户方面。 方法执行10k次后,JIT将开始优化,此处为run()
,随着时间的流逝,JIT将进行更多优化。
为什么经过的时间不同? 是FileWriter的问题还是文件系统的问题?
打开和关闭文件非常昂贵。 您的瓶颈可能在操作系统或HDD中。 即代码不能很好地扩展。 您很可能少于10个CPU,因此一次只能运行这么多线程。 当您的代码无法很好地扩展且系统过载时,您将获得无与伦比的性能结果。
问题出在您的程序中,试图使系统过载。 使用更多的CPU将为您提供更多的处理能力,并且您正在使用它来从10个不同方面锤击您的OS。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.