线程安全写入同一文件

我创建了这个方法来通过多个线程将文本写入同一个文件:


public static void ThreadsafeWriter(String text, String file) throws IOException {

    String nodeValue = text;

    BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));

    synchronized (writer) {

        String[] words = nodeValue.split(" ");

        for (String word: words) {

            writer.write(word);

            writer.newLine();

        }

        writer.close();

    }

}

我想问一下有没有错误,会不会导致异常?


潇湘沐
浏览 164回答 2
2回答

慕娘9325324

你的synchronized块不会做任何事情;这不是线程安全的。同步基于每个实例:synchronized (writer)意味着没有其他监视器可以在同一个writer实例上进入同步块。但是你只是在你的方法中创建了那个 writer,你从来没有将它发布到另一个线程;没有其他线程会看到该对象,更不用说尝试在其上输入同步块了。您需要创建类似于从文件路径到要锁定的对象的静态映射(并注意别名等,它们可能具有不同的路径但引用同一个文件)。当然,这些都不会阻止另一个进程写入文件。文件的原子性很棘手。一种常见的技术是写入一个临时的随机文件,然后将该文件移动到目标路径。

拉丁的传说

您可以通过不使用writer变量而是使用另一个static变量进行同步来实现它。这样,调用此方法的所有对象都将使用相同的对象进行同步,而不是每次调用创建的新 BufferedWriter。例子:public class SyncExample{ private static Object lock = new Object(); // the object for locks does not have to be anything special.   public static void ThreadsafeWriter(String text, String file) throws IOException {String nodeValue = text;    BufferedWriter writer = new BufferedWriter(new FileWriter(file, true));    synchronized (lock ) {        String[] words = nodeValue.split(" ");        for (String word: words) {            writer.write(word);            writer.newLine();        }       writer.close();    }}}编辑:我刚刚重新阅读了您的问题,抱歉。如果您尝试写入的文件在调用之间相同或不同,请考虑我的“修复”确实会忽略。它只是“不可能”“同时”写入两个任何文件。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java