java - 如何同步多个线程写入文件

标签 java multithreading io

我正在使用 ExecutorService 让多个线程将文本写入文件,但我无法同步 run() 方法,而不是拥有正确的行按行字符串我问,我混合了字符串的所有字符,因为它们是同时写入的。

import java.io.BufferedReader
...

class WriteDns implements Runnable {

File file;
String text;

WriteDns(File file, String text) {
    this.file = file;
    this.text = text;
}

public void run() {
    synchronized (this) {
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(file)))) {
            bw.write(turnDns() + "\n");
        } catch (IOException e) {
            System.out.println("Error");
        }
    }
}

public String turnDns() {
    int space = text.indexOf(' ');
    String ip = text.substring(0, space);
    String theRest = text.substring(space);
    String temp = ip;
    try {
        ip = InetAddress.getByName(ip).getHostName();
        if (ip == temp)
            return "NotFound " + theRest;
        return ip + " " + theRest;
    } catch (UnknownHostException e) {
        System.out.println("Error in change");
        return "-changeErr " + theRest;
    }
}

}

public class Main00 {

static File oldFile = new File("oldfile.txt");

public static void main(String[] args) {

    readLines();

}

public static void readLines() {
    try (BufferedReader br = new BufferedReader(new FileReader(oldFile))) {
        File f = new File("file.txt");
        ExecutorService service = Executors.newFixedThreadPool(10);
        for (String t = br.readLine(); t != null; t = br.readLine()) {
            service.execute(new WriteDns(f, t));
        }
        service.shutdown();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

最佳答案

您正在同步this,但您正在为每个线程创建一个新的线程工作实例,因此每个线程都会锁定自身,并且从不等待任何其他线程。您需要锁定一个对所有线程都可见的对象,可能是一个静态对象,或者在实例化 WriteDns 时传入一个锁定对象。

话虽如此,在一个文件上打开多个线程本质上很容易出现像您遇到的问题,并且您从多个线程写入中没有任何好处,因为您的瓶颈是您的存储介质而不是处理器。您应该让多个线程向一个专用写入器线程提供信息/数据,该写入器线程对您要写入的文件具有独占访问权限,如 @FlorianSchaetz 建议的那样。

关于java - 如何同步多个线程写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32022290/

相关文章:

multithreading - 如何限制对单个实时资源的并发访问

c++ - 线程上的 Boost.Asio 并发问题

java - 使用输出流将数据添加到特定文件

java - 从正在运行的应用程序窗口获取像素颜色 - JAVA

java - 如何在不使用准备好的语句的情况下清理 SQL

java - 如何在android studio中将正方形居中

java - 从线程调用的方法访问 ThreadLocal 值?

java - 处理程序更改 UI 导致 CalledFromWrongThreadException

c++ - CERN 根目录 : generate streamer for an extern "C" struct in a namespace

java - 使用Java修改文件内容