使用FileLock在Java中锁定文件

时间:2015-05-19 21:03:10

标签: java multithreading locking

我正在尝试使用Java FileLock写入文件,禁止所有其他进程和线程从中读取或写入文件,直到我完成它为止。给定this question及其答案,在我看来,这是我想要的完美工具 - 文件访问的互斥锁。

但是,我非常关注JavaDocs

中的这段文字
  

代表整个Java虚拟机保存文件锁。他们   不适合控制多个线程对文件的访问   在同一个虚拟机中。

有人可以减轻我的恐惧还是指向正确的方向?听起来FileLock根本不能用来保持文件中的不同线程,即使另一个线程已经获得它。如果是这种情况,是否有其他规范的Java方法可以保护其他线程?

2 个答案:

答案 0 :(得分:4)

FileLock是进程级别锁定,因此不会保护文件不受具有锁定的进程内多个线程的并发访问。

您需要使用FileLock的组合来防止来自其他进程的并发访问以及一些其他同步机制(如用于访问文件的synchronized方法)以防止并发通过自己的线程访问。

答案 1 :(得分:2)

我会按如下方式实现:

interface FileOperator {
  public void operate(File file);
}

class FileProxy {
  private static final ConcurrentHashMap<URI, FileProxy> map =
    new ConcurrentHashMap<>();

  private final Semaphore mutex = new Semaphore(1, true);

  private final File file;

  private final URI key;

  private FileProxy(File file) {
    this.file = file;
    this.key = file.toURI();
  }

  public static void operate(URI uri, FileOperator operator) {
    FileProxy curProxy = map.get(uri);
    if(curProxy == null) {
      FileProxy newProxy = new FileProxy(new File(uri));
      FileProxy curProxy = map.putIfAbsent(newProxy.key, newProxy);
      if(curProxy == null) {
        curProxy = newProxy; // FileProxy was not in the map
      }
    }

    try {
      curProxy.mutex.acquire();
      operator.operate(curProxy.file);
    } finally {
      curProxy.mutex.release();
    }
  }
}

正在使用文件的线程实现FileOperator或类似的东西。文件隐藏在FileProxy后面,该ConcurrentHashMap维护密钥的静态FileProxy(URI,或绝对路径,或其他一些文件不变)值(FileProxy)对。每个Semaphore维护一个充当互斥锁的operate - 这是用一个许可证初始化的。调用静态FileProxy方法时,如果不存在,则从URI创建新的FileOperator;然后将FileProxy添加到acquire队列中;在互斥锁上调用FileOperator以确保一次只能有一个线程对该文件进行操作;最后FileProxy做了它的事。

在此实现中,永远不会从ConcurrentHashMap中删除FileProxy个对象 - 如果这是一个问题,那么解决方案是将WeakReference个对象包装在SoftReferencemap.replace这样可以对它们进行垃圾回收,然后在reference.get() == null时调用loop { ; this is the color of green boxed monsters to attack PixelSearch, X, Y, 0, 0, %A_ScreenWidth%, %A_ScreenHeight%, 0x00FF00, 0, fast if (ErrorLevel = 0) { MouseClick, left, %X%, %Y% } else { ; if no monster present in screen, press teleport to search monsters Send {F1} } } return 以确保只有一个帖子替换了GC的引用。