2.6 File Locking
When multiple simultaneously executing programs need to modify the same file, they need to communicate in some way, or the file can easily become damaged. File locks can solve this problem. A file lock controls access to a file or a range of bytes within a file.
Suppose your application saves a configuration file with user preferences. If a user invokes two instances of the application, it could happen that both of them want to write the configuration file at the same time. In that situation, the first instance should lock the file. When the second instance finds the file locked, it can decide to wait until the file is unlocked or simply skip the writing process.
To lock a file, call either the lock or tryLock methods of the FileChannel class.
FileChannel = FileChannel.open(path); FileLock lock = channel.lock();
or
FileLock lock = channel.tryLock();
The first call blocks until the lock becomes available. The second call returns immediately, either with the lock or with null if the lock is not available. The file remains locked until the channel is closed or the release method is invoked on the lock.
You can also lock a portion of the file with the call
FileLock lock(long start, long size, boolean shared)
or
FileLock tryLock(long start, long size, boolean shared)
The shared flag is false to lock the file for both reading and writing. It is true for a shared lock, which allows multiple processes to read from the file, while preventing any process from acquiring an exclusive lock. Not all operating systems support shared locks. You may get an exclusive lock even if you just asked for a shared one. Call the isShared method of the FileLock class to find out which kind you have.
Be sure to unlock the lock when you are done. As always, this is best done with a try-with-resources statement:
try (FileLock lock = channel.lock()) { access the locked file or segment }
Keep in mind that file locking is system-dependent. Here are some points to watch for:
On some systems, file locking is merely advisory. If an application fails to get a lock, it may still write to a file that another application has currently locked.
On some systems, you cannot simultaneously lock a file and map it into memory.
File locks are held by the entire Java virtual machine. If two programs are launched by the same virtual machine (such as an applet or application launcher), they can’t each acquire a lock on the same file. The lock and tryLock methods will throw an OverlappingFileLockException if the virtual machine already holds another overlapping lock on the same file.
On some systems, closing a channel releases all locks on the underlying file held by the Java virtual machine. You should therefore avoid multiple channels on the same locked file.
Locking files on a networked file system is highly system-dependent and should probably be avoided.