javafile-lockingfilechannelfilelock

What's the purpose of waiting in FileChannel.lock if OverlappingFileLockException is thrown anyway?


FileChannel.lock allows to create file lock in Java (I use the approach from How can I lock a file using java (if possible) with FileOutputStream in order to avoid NonWritableChannelException):

FileOutputStream out = new FileOutputStream(file);
try {
    java.nio.channels.FileLock lock = out.getChannel().lock();
    try {
        ...
    } finally {
        lock.release();
    }
} finally {
    out.close();
}

An essential part working with locks waiting for their release by the process holding the resource. Therefore lock

will block until the region can be locked, this channel is closed, or the invoking thread is interrupted, whichever comes first.

However, everytime I'm attempting to lock the same file (region spanning the complete file) I get a OverlappingFileLockException which is thrown

If a lock that overlaps the requested region is already held by this Java virtual machine, or if another thread is already blocked in this method and is attempting to lock an overlapping region

That contradicts the logic of locking and makes it impossible to work with file locks because it's necessary to synchronize the resource access manually if only one thread in the queue is allowed (further ones immediately throw OverlappingFileLockException).

Using lock(0, Long.MAX_VALUE, false) where false refers to the shared property doesn't change this behavior.


Solution

  • File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine.

    reads "They cannot be used for controlling because only one lock per JVM can be acquired".

    "Suitable" can mean a lot of things in this context including notions of inefficiency in comparison to thread-based locks. Those have to be used to guard the file lock when accessing it from multiple threads.