Java中的多线程单文件写入

Java中的多线程单文件写入,java,multithreading,oop,Java,Multithreading,Oop,这个问题似乎很常见,但当多个线程写入同一个文件(Excel)时,我会遇到一些问题。这是我的密码: public class XLWriter { private XLWriter() { } private static class SingletonHelper { private static final XLWriter INSTANCE = new XLWriter(); } public static synchronized XLWriter getInstance()

这个问题似乎很常见,但当多个线程写入同一个文件(Excel)时,我会遇到一些问题。这是我的密码:

public class XLWriter {

private XLWriter() {
}

private static class SingletonHelper {
    private static final XLWriter INSTANCE = new XLWriter();
}

public static synchronized XLWriter getInstance() {
    return SingletonHelper.INSTANCE;
}

public static synchronized void writeOutput(Map<String, String> d) {
    try {
        --- Write file
    } catch (Exception e) {
        SOP("Not able to write output to the output file.");
    }
}

public static void createWorkBook(String fileName, String sheetName)
        throws IOException {
    try {
        -- Create workbook
    } catch (WriteException e) {
        System.out.println("Could not create workbook" + e);
    }
}
公共类XLWriter{
私人XLWriter(){
}
私有静态类SingletonHelper{
私有静态最终XLWriter实例=新XLWriter();
}
公共静态同步XLWriter getInstance(){
返回SingletonHelper.INSTANCE;
}
公共静态同步的void writeOutput(映射d){
试一试{
---写入文件
}捕获(例外e){
SOP(“无法将输出写入输出文件”);
}
}
公共静态void create工作簿(字符串文件名、字符串名称)
抛出IOException{
试一试{
--创建工作簿
}捕获(写入异常e){
System.out.println(“无法创建工作簿”+e);
}
}

我正在使用testng framework,有10个线程试图写入同一个文件。许多线程无法写入该文件,并进入异常块中…更好的方法是什么?任何代码示例都将极大地帮助我,因为我完成此任务的时间非常少。谢谢。

您不需要同步纯读取,因此
 public static synchronized XLWriter getInstance()
可以在没有任何错误的情况下执行
synchronized
。您只需要同步写入,其中多个线程可能同时写入/读取相同的数据

有两件事可以解决您的问题。最简单的一件事是创建一个特殊的写入函数,该函数是唯一要同步的函数:

private void write(final File f, final Map<String, String> output) {
  synchronized(f) {
    // do the write
  }
}
只要确保在某个地方有一个解决方案,一旦完成,就可以关闭hashmap中的所有文件


对于进一步的想法:您还可以创建一个写线程,其唯一目的是将内容写入该文件。如果该线程有一个,其他线程可以将其部分添加到此队列而不是文件,然后继续执行它们正在执行的任何操作,而写线程是唯一有权访问该文件的线程。因此,没有写线程可能会出现问题,线程安全完全由ConcurrentBlockingQueue处理。

它是否与单个线程一起工作?
createWorkBook
方法不是
synchronized
。这是有意的吗?这两个方法中的哪一个失败?会出现什么类型的异常?创建一个队列,每个线程将其数据写入其中。创建一个单独的写入线程,读取队列数据并保存到磁盘。非常感谢您的详细回答。非常有用。万分感谢。
public void getFileFor(String filename) {
  File newFile = File(filename);
  File inList = fileHashMap.putIfAbsent(newFile);
  if (inList != null) {
    return inList;
  } else {
    return newFile;
  }
}