简体   繁体   English

从多个线程写入多个文本文件

[英]Write to multiple text files from multiple threads

I'm doing some experiments about multithreading. 我正在做一些关于多线程的实验。

When the program runs to the output part, (using java.io.FileWriter ) sometimes it can go through quickly, but sometimes it just stuck on there. 当程序运行到输出部分时(使用java.io.FileWriter ),有时可以快速通过,但有时只是停留在该位置。

Is the FileWriter 's problem? FileWriter的问题吗? Here is the simplified code: 这是简化的代码:

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();
        }
    }
}

And here is my result: 这是我的结果:

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

I runs it three times, why are the elapsed times different? 我运行了3次,为什么经过的时间不同? Is it the FileWriter 's problem or the file system's? FileWriter的问题还是文件系统的问题?

You have at least two problems: 您至少有两个问题:

  • you make way too many syscalls; 您让太多的系统调用; basically, for one loop of each thread you do open() , write() , (maybe flush() and finally close() ; at least 300k syscalls! 基本上,对于每个线程一个循环,您可以执行open()write() ((可能是flush() ,最后是close() ;至少300k syscalls!
  • you create 100k FileWriter objects, 100k File objects; 您创建100k FileWriter对象,100k File对象; the gc needs to handle all of them; gc需要处理所有这些问题; and since the gc runs in a thread by itself and is scheduled like any other threads, it will run more or less often. 由于gc本身在线程中运行,并且像其他线程一样进行调度,因此它将或多或少地运行。

The problem is therefore more with your program than anything OS-related... The JIT can't do anything for you here. 因此,问题出在您的程序上,而不是与操作系统相关的任何事情……JIT在这里无法为您做任何事情。

Also, since you use Java 7, you should consider using Files.newBufferedWriter() -- only once per thread, of course, not 10000 times! 另外,由于使用Java 7,因此应考虑使用Files.newBufferedWriter() -每个线程仅使用一次,当然,不要使用10000次!


Further note about the "syscall problem": at least on Unix systems, but other OSes probably work the same, each time you make a syscall, your process has to enter kernel mode the time that the syscall is executed; 关于“系统调用问题”的进一步说明:至少在Unix系统上,但是其他操作系统可能工作相同, 每次执行系统调用时,您的进程都必须在执行系统调用时进入内核模式; this is not free. 这不是免费的。 Even if on modern systems the cost is not that significant, it is nevertheless significantly higher than not having to do user->kernel->user. 即使在现代系统的成本是不是显著,但它仍然是比没有做用户>内核级>用户显著较高。


Well, OK, I lied a little; 好吧,我撒了一点谎。 the JIT does kick in but it will only optimize the user side of things. JIT确实可以实现,但只会优化用户方面。 The JIT will start to optimize after 10k executions of a method, here your run() , and optimize more as time passes. 方法执行10k次后,JIT将开始优化,此处为run() ,随着时间的流逝,JIT将进行更多优化。

why are the elapsed times different? 为什么经过的时间不同? Is it the FileWriter's problem or the file system's? 是FileWriter的问题还是文件系统的问题?

Opening and closing files is very expensive. 打开和关闭文件非常昂贵。 Your bottleneck is likely to be in your OS or your HDD. 您的瓶颈可能在操作系统或HDD中。 ie the code doesn't scale well. 即代码不能很好地扩展。 Most likely you have less than 10 CPUs so only so many threads are running at once. 您很可能少于10个CPU,因此一次只能运行这么多线程。 When you have code which doesn't scale well and an overloaded system you get wildly varing performance results. 当您的代码无法很好地扩展且系统过载时,您将获得无与伦比的性能结果。

The problem is in your program trying to overload your system. 问题出在您的程序中,试图使系统过载。 Using more CPUs gives you more processing power and you are using it to hammer your OS from 10 different sides. 使用更多的CPU将为您提供更多的处理能力,并且您正在使用它来从10个不同方面锤击您的OS。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM