0

I haven't found anything specific, only threads like that, which doesn't show the implementation.

I need to create a file lock shared between two or more processes(not threads!). I need to read/write in a file in one process and guarantee that no other process writes to the file in the same time. FileChannel.lock() doesn't do the job, because it throws an exception(OverlappingFileLockException) whenever the lock exists.

I have two ideas how to achieve a inter-process mutex, but both seems a little bit bad to me.

  1. Repeat locking action until it works - quite disgusting, but simple and it should work I guess?

    RandomAccessFile rFile = new RandomAccessFile(file, "rw");
    FileChannel channel = rFile.getChannel();
    FileLock lock;
    boolean locked = false;
    while(!locked) {
        try {
            lock = channel.lock();
            locked = true;
        } catch(OverlappingFileLockException e) {
            Thread.sleep(10);
        }
    }
    lock.release();
    
  2. Whenever the exception is thrown, transform the current process into a server. Use ServerSocket to listen to other processes and Socket to communicate that lock.release() has been called. This one sounds like using a cannon to kill a fly to me.

Is any of these 2 correct way of handling my problem? Or is there an already existing Java mechanism that allows locking a file across processes?

MrGrzyboo
  • 77
  • 8
  • You want two processes to lock the same file? – Malt Feb 15 '18 at 22:57
  • Yes: 1 file, order of locking is not important. I just want to ensure that 2 processes cannot access the file in the same time. – MrGrzyboo Feb 15 '18 at 22:59
  • Why is throwing an exception a problem? `while (true) { try { lock file; do your thing; unlock file; return; } catch { don't care; maybe wait a sec though } }` – cHao Feb 15 '18 at 23:02
  • I seem to recall that the JVM specifies that file locking may not succeed and is platform dependent. Only locking within a JVM is guaranteed, locking with another process is not. I.e., your code may not be portable, so be sure to test on each platform. – markspace Feb 15 '18 at 23:28
  • This may explain why there is no built-in Java mechanism for it. I will make sure to test it on the platform I'm interested in. – MrGrzyboo Feb 20 '18 at 01:43

1 Answers1

1
try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
    while (raf.getChannel().tryLock() == null) {
        Thread.sleep(10);
    }
    // lock acquired
}

The lock will be automatically released (indirectly - via closing the RandomAccessFile) by the try-with-resurces block.
BTW the OverlappingFileLockException is thrown because the current JVM already has the lock, or a thread of the current JVM is already waiting for it.

Bax
  • 4,260
  • 5
  • 43
  • 65