为了账号安全,请及时绑定邮箱和手机立即绑定

线程安全写入同一文件

线程安全写入同一文件

潇湘沐 2021-09-03 21:59:15
我创建了这个方法来通过多个线程将文本写入同一个文件: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();    }}我想问一下有没有错误,会不会导致异常?
查看完整描述

2 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

你的synchronized块不会做任何事情;这不是线程安全的。

同步基于每个实例:synchronized (writer)意味着没有其他监视器可以在同一个writer实例上进入同步块。但是你只是在你的方法中创建了那个 writer,你从来没有将它发布到另一个线程;没有其他线程会看到该对象,更不用说尝试在其上输入同步块了。

您需要创建类似于从文件路径到要锁定的对象的静态映射(并注意别名等,它们可能具有不同的路径但引用同一个文件)。当然,这些都不会阻止另一个进程写入文件。

文件的原子性很棘手。一种常见的技术是写入一个临时的随机文件,然后将该文件移动到目标路径。


查看完整回答
反对 回复 2021-09-03
?
拉丁的传说

TA贡献1789条经验 获得超8个赞

您可以通过不使用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();

    }

}



}

编辑:我刚刚重新阅读了您的问题,抱歉。如果您尝试写入的文件在调用之间相同或不同,请考虑我的“修复”确实会忽略。它只是“不可能”“同时”写入两个任何文件。

查看完整回答
反对 回复 2021-09-03
  • 2 回答
  • 0 关注
  • 163 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信