java从多个线程写入多个文本文件
我正在做一些关于多线程的实验
当程序运行到输出部分时,(使用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
我运行了三次,为什么运行时间不同?
是FileWriter
的问题还是文件系统的问题
# 1 楼答案
您至少有两个问题:
open()
,write()
,(可能flush()
,最后close()
;至少300k个系统调用FileWriter
个对象,100kFile
个对象;gc需要处理所有这些问题;由于gc单独在一个线程中运行,并且与其他线程一样被调度,因此它将或多或少地运行李>因此,问题更多的是你的程序,而不是任何操作系统相关的。。。JIT在这里帮不了你什么
此外,由于使用java 7,所以应该考虑使用{{CD7}},每线程只使用一次,当然不是10000次!p>
进一步注意“系统调用问题”:至少在Unix系统上,但其他操作系统可能工作相同,每次进行系统调用时,进程必须在执行系统调用时进入内核模式;这不是免费的。即使在现代系统上,成本没有那么高,但仍明显高于不必须做的用户->;内核->;用户
好吧,我撒了一点谎;JIT确实起作用,但它只会优化事情的用户端。JIT将在方法执行10k次后开始优化,这里是
run()
,并随着时间的推移进行更多优化# 2 楼答案
打开和关闭文件非常昂贵。您的瓶颈可能在操作系统或硬盘中。i、 代码的伸缩性不好。很可能您的CPU少于10个,因此一次只能运行这么多线程。当您的代码不能很好地扩展,并且系统过载时,您会得到各种各样的性能结果
问题在于程序试图使系统过载。使用更多的CPU可以提供更多的处理能力,您可以从10个不同的方面使用它来敲打您的操作系统