ファイルロック-FileLock

2649 ワード

最近flumeの一部の機能のソースコードを見ていますが、FileLockの使用については、実は多くのオープンソースフレームワークに関連しています.私が見たのはlucene、zookeeper、hadoop、esなどのオープンソースフレームワークがあります.以下、簡単にFileLockを紹介します.
1,FileLockは排他ロックであり,異なるプログラム(JVM)による同一ファイルへの同時アクセスを制御する.2、書き込みファイル(w)にロックをかけることができ、書き込み可能なファイルでなければならない.そうしないと、リターン:java.nio.channels.NonWritableChannelException例外は、ロックされたファイルへのアクセスが同じプロセスでしか得られないことを保証します.他のプロセスでは、変更ファイルにアクセスできないか、ファイルのディレクトリを削除できません.
3.排他ロックであるため、プロセス間でこのファイルに順次アクセスすることを保証し、データエラーを回避することができる.s
4,FileLockのライフサイクルは、FileLockを呼び出す.release()、またはChannel.close()またはJVMがオフの場合、ライフサイクルは終了します.
5,FileLockのlockとtryLockは1回しか呼び出せず,解放後もロックを取得し続けることができない.
java.io.File.deleteOnExit()はFileLockライフサイクルの終了時にファイルが削除され、一般的に一時ファイルの削除に使用されます.仮想マシンを強制的に閉じると、ファイルは削除されません.テストコード:
public static void main(String[] args) throws IOException {

    File f = null;

    try {

        f = File.createTempFile("tmp", ".txt");

        System.out.println("Path: " + f.getAbsolutePath());

        f.deleteOnExit();

        f = File.createTempFile("tmp", null);

        System.out.print("Path: " + f.getAbsolutePath());

        f.deleteOnExit();

    } catch (Exception e) {

        e.printStackTrace();

    }

 }

FileLock排他ロックを取得したファイルは、deleteでは削除できません.deleteOnExit()でFileLockライフサイクル終了時に削除できます.テストコード:
    FileLock fileLock = null;
    File file = new File("D:\\trylock\\", "fish.lock");
    RandomAccessFile randAccessfile = new RandomAccessFile(file, "rws");
    //  , , , 
    // randAccessfile.getChannel().lock();
    //  , , ,tryLock() null 
    fileLock = randAccessfile.getChannel().tryLock();
    if (fileLock != null && file.isDirectory()) {
        file.delete();
    } else if (fileLock != null && file.isFile()) {
//	        file.delete();//  , deleteOnExit
        file.deleteOnExit();//  , 
    }
    if (fileLock == null) {
        return;
    } else {
        fileLock.release();
        fileLock.channel().close();
        fileLock = null;
    }

Flumeでの使用:
private FileLock tryLock(File dir) throws IOException {
    File lockF = new File(dir, FILE_LOCK);
    lockF.deleteOnExit();
    RandomAccessFile file = new RandomAccessFile(lockF, "rws");
    FileLock res = null;
    try {
      res = file.getChannel().tryLock();
    } catch(OverlappingFileLockException oe) {
      file.close();
      return null;
    } catch(IOException e) {
      LOGGER.error("Cannot create lock on " + lockF, e);
      file.close();
      throw e;
    }
    return res;
  }