如何在java中同步非静态方法变量(对象)

时间:2016-09-01 08:57:25

标签: java multithreading synchronization

我有一个写入文件的方法。我需要同步文件对象

class MessageFile{

public static final String  fileName="Main.html"
@AutoWired
AppConifg appconfig;

 public boolean writeToFile(String fileContent) throws  Exception{

        String path = appConfig.getNewsPath() + File.separator + fileName; // getNewsPath is non-static method
        final  File alertFile= new File(path);
        FileOutputStream out = null;
        synchronized (alertFile) {
          if (!alertFile.exists()) {
              alertFile.createNewFile();
          }
          try {
              out = new FileOutputStream(alertFile, false);
              out.write(fileContent.getBytes());
              out.flush();
          } finally {
              if (out != null) {
                  out.close();
              }
          }
      }
        return true;
    }


    }

但是上面的代码不会对文件对象采取锁定独占锁定,因为此类的另一个实例可以锁定此类并写入文件。 所以我想如何处理这种情况? 我发现一个解决方法是创建一个附加时间戳的临时文件名(因此临时文件名将始终是唯一的),在向其写入内容之后,将首先删除原始文件,然后将临时文件重命名为原始文件名。

4 个答案:

答案 0 :(得分:0)

如果它是唯一访问该文件的对象,您可以尝试在MessageFile.class上进行同步。

答案 1 :(得分:0)

每次运行方法时,您都在创建新的File对象(alertFile),因此每次运行方法时锁都不会执行任何操作 - 您需要具有静态{{1}实例在所有方法调用中共享。

如果每次运行该方法时File可能不同,您可以创建path实例并像这样使用它:

  1. 获取文件的路径。
  2. 如果此路径没有关联static Map<String, File>,请创建它。
  3. 否则,从map中恢复现有的File实例。
  4. 将此File用作锁定并对其执行操作。
  5. 基于修改后答案的示例:

    File

答案 2 :(得分:0)

您的程序没有获得文件的独占锁定,因为您在类synchronized的实例之间没有共享的本地变量alertFile上使用MessageFile(每个对象都有自己的alertFile)。您有两种可能性来解决这个问题:

1-创建一些静态对象并在其上进行同步(您可以使用fileName,因为它已经存在)。

2-所有对象中的引用都指向同一个对象(例如,在构造函数中传递)并在其上进行同步。

答案 3 :(得分:0)

在类级别对象上进行同步,即MessageFile.class或使用静态同步方法wrtietofile()。它将确保一次只有一个线程写入文件。它还保证一旦线程将整个数据写入文件,就会释放锁。