Java - 多个线程写入同一个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19207845/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 15:02:59  来源:igfitidea点击:

Java - multiple threads writing to same file

javamultithreading

提问by Ankit Rustagi

I am trying to write some content to a file, through multiple threads in Java. Each thread reads a different input file, does some computation and writes some (different) content to the common output file. The problem is that in the end, the output file only contains the content written by the last terminating thread and not the content from the other threads. Relevant code for the threads -

我正在尝试通过 Java 中的多个线程将一些内容写入文件。每个线程读取不同的输入文件,进行一些计算并将一些(不同的)内容写入公共输出文件。问题是最终输出文件只包含最后一个终止线程写入的内容,而不包含其他线程的内容。线程的相关代码 -

public void run()
{
    try
    {
        File file = new File("/home/output.txt");
        if (!file.exists()) 
        {
             file.createNewFile();
        }
        FileWriter fw = new FileWriter(file.getAbsoluteFile());
        BufferedWriter bw = new BufferedWriter(fw);

        BufferedReader br = new BufferedReader(new FileReader(inputfile)); // each thread reads a different input file
        String line="";

        while((line=br.readLine())!=null)
        {
            String id = line.trim();               // fetch id

            StringBuffer sb = processId(userId);   // process id

            synchronized(this){
            bw.write(sb.toString() + "\n");        // write to file
            }
        }
        bw.close();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

How do i make all threads write their content to the common file ?

如何让所有线程将它们的内容写入公共文件?

采纳答案by Reimeus

Use the constructor for FileWriterthat uses append mode

使用FileWriter使用追加模式的构造函数

FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);

回答by Anuj Aneja

FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);

FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);

should be used which indicates append mode.

应该使用它指示追加模式。

回答by Java World

Few points related to your code :

与您的代码相关的几点:

1.The way you are creating the FileWriteris not correct . If you want to append data to the file, use the constructor that contains an additional booleanargument ( Make it true):

1.您创建的FileWriter方式不正确。如果要将数据附加到文件,请使用包含附加boolean参数 ( Make it true)的构造函数:

public FileWriter(File file,boolean append) throws IOException

For example :

例如 :

FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);

2.You are talking about multiple threads that will share a common file , but I couldn't see any synchronized block in your code . Use synchronization to ensure that only one thread can access the shared resource at a time.

2.您正在谈论将共享一个公共文件的多个线程,但我在您的代码中看不到任何同步块。使用同步来确保一次只有一个线程可以访问共享资源。

回答by dalvarezmartinez1

I'm a newbie. SO I MIGHT BE WRONG! But your code MAY or MAY NOT work. Is that the run of a Runnable or thread? Note this:

我是新手。所以我可能错了!但是您的代码可能会或可能不会工作。那是 Runnable 还是线程的运行?请注意:

MyClass implements Runnable {

 public void run() {
 ....synchronized(this)..
 }

}

Thread t1 = new Thread(new MyClass());
Thread t2 = new Thread(new MyClass());

Many of us do it like that(I did it, do it:), and yey! Each thread will obtain a lock on different obj, and you can end up with unexpected results, unless the OS uses some mechanism to sync writes to the same file (I don't know). If it does, then your synchonized is useless(useless anyway in my example), if it doesn't you're pretty.... Also as a note, there may be another process using this output.txt of which we have no idea...complicated stuff, at least for me

我们很多人都是这样做的(我做到了,做到了:),是的!每个线程都会在不同的 obj 上获得一个锁,你最终可能会得到意想不到的结果,除非操作系统使用某种机制来同步写入同一个文件(我不知道)。如果是这样,那么你的同步是无用的(在我的例子中无论如何都没用),如果不是,你很漂亮......另外作为说明,可能有另一个进程使用这个 output.txt 我们没有想法......复杂的东西,至少对我来说

My opinion is that synchronized is useful if you have oneinstance of the class which SHARES, MUTABLE, STATE. (Let's forget about synchronized and static for now)

我的观点是,如果您有一个SHARESMUTABLESTATE类的实例,则synchronized 很有用。(让我们暂时忘记同步和静态)

Does MyClass have state? No. Is it shared? NO, not in my example. Will it work? Not like this. Probably like this?

MyClass 有状态吗?不,是共享的吗?不,不是在我的例子中。它会起作用吗?不是这样的。大概是这样?

MyClass mc = new MyClass()
Thread t1 = new Thread(mc);
Thread t2 = new Thread(mc);

PS: I forgot to call start on every thread.

PS:我忘了在每个线程上调用 start 。

回答by jayesh

Have a single file writer thread which keeps reading from blocking queue and writing to a file. All other 20 threads will just put the data in blocking queue. This will prevent contention between 20 writer threads.

有一个单一的文件写入线程,它保持从阻塞队列读取和写入文件。所有其他 20 个线程只会将数据放入阻塞队列。这将防止 20 个编写器线程之间发生争用。