【问题标题】:How to synchronize multiple threads writing into a file如何同步多个线程写入文件
【发布时间】:2015-08-15 06:43:19
【问题描述】:

我正在使用 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();
    }
}

}

【问题讨论】:

  • 线程池的要点是并行运行多个操作,但您必须按顺序写入文件,否则您会遇到帖子中提到的问题。为什么要使用线程池?
  • 建议:使用 ConcurrentLinkedQueue 创建一个新线程。该线程仅检查队列中的 ne 数据并将该数据写入文件中。所有其他线程仅将其数据块(作为完整对象)添加到队列中。这样,写入线程是唯一访问文件并写入定义明确的数据块的线程。
  • @FlorianSchaetz 知道发生了什么。做那个OP。

标签: java multithreading io


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多