Mastering Java NIO File Locks: Exclusive & Shared Lock Techniques

This tutorial explains how to use Java NIO's FileChannel to acquire exclusive and shared file locks, covering lock types, required channel modes, code examples for FileOutputStream, RandomAccessFile, and FileInputStream, and discusses platform-specific considerations and common exceptions.

Programmer DD
Programmer DD
Programmer DD
Mastering Java NIO File Locks: Exclusive & Shared Lock Techniques

1. Overview

When reading or writing files, a proper file‑locking mechanism is required to ensure data integrity for concurrent I/O applications.

This tutorial introduces various ways to achieve this using the Java NIO library.

2. Introduction to File Locks

Generally, there are two kinds of locks:

Exclusive lock – also called a write lock

Shared lock – also called a read lock

An exclusive lock prevents all other operations, including reads, while a shared lock allows multiple processes to read simultaneously but blocks writers.

3. File Locks in Java

The Java NIO library supports OS‑level file locking. The FileChannel class provides lock() and tryLock() methods for this purpose.

You can obtain a FileChannel from FileInputStream, FileOutputStream, or RandomAccessFile via the getChannel() method, or create one directly with the static open method:

try (FileChannel channel = FileChannel.open(path, openOptions)) {
    // write to the channel
}

4. Exclusive Lock

When writing to a file, an exclusive lock prevents other processes from reading or writing the file.

Obtain an exclusive lock by calling FileChannel.lock() or FileChannel.tryLock(). Overloaded methods allow specifying position, size, and a shared flag (must be false for exclusive locks).

lock(long position, long size, boolean shared)
tryLock(long position, long size, boolean shared)

Exclusive locks require a writable channel. Examples:

4.1. Exclusive Lock with FileOutputStream

try (FileOutputStream fos = new FileOutputStream("/tmp/testfile.txt");
     FileChannel channel = fos.getChannel();
     FileLock lock = channel.lock()) {
    // write to the channel
}

If the region is already locked, lock() throws OverlappingFileLockException. tryLock() returns null when the lock cannot be acquired.

4.2. Exclusive Lock with RandomAccessFile

try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "rw");
     FileChannel channel = file.getChannel();
     FileLock lock = channel.lock()) {
    // write to the channel
}

Attempting to lock a read‑only channel results in NonWritableChannelException.

4.3. Exclusive Lock Requires a Writable Channel

Path path = Files.createTempFile("foo", "txt");
try (FileInputStream fis = new FileInputStream(path.toFile());
     FileLock lock = fis.getChannel().lock()) {
    // unreachable code
} catch (NonWritableChannelException e) {
    // handle exception
}

5. Shared Lock

A shared lock (read lock) requires a readable channel. Obtain it via FileInputStream, RandomAccessFile, or FileChannel.open with StandardOpenOption.READ:

try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ);
     FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {
    // read from the channel
}

For shared locks, the third argument of lock() must be true. The entire file can be locked, or a specific region by adjusting the first two parameters.

5.1. Shared Lock with FileInputStream

try (FileInputStream fis = new FileInputStream("/tmp/testfile.txt");
     FileChannel channel = fis.getChannel();
     FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {
    // read from the channel
}

5.2. Shared Lock with RandomAccessFile

try (RandomAccessFile file = new RandomAccessFile("/tmp/testfile.txt", "r");
     FileChannel channel = file.getChannel();
     FileLock lock = channel.lock(0, Long.MAX_VALUE, true)) {
    // read from the channel
}

5.3. Shared Lock Requires a Readable Channel

Path path = Files.createTempFile("foo", "txt");
try (FileOutputStream fos = new FileOutputStream(path.toFile());
     FileLock lock = fos.getChannel().lock(0, Long.MAX_VALUE, true)) {
    // unreachable code
} catch (NonWritableChannelException e) {
    // handle exception
}

6. Considerations

File locking is difficult and non‑portable; design your locking logic accordingly.

On POSIX systems, locks are advisory, requiring cooperating processes. On Windows, locks are exclusive unless sharing is allowed.

7. Summary

This tutorial reviewed several options for acquiring file locks in Java, explained exclusive and shared lock mechanisms, demonstrated practical code examples, and highlighted typical exceptions you may encounter.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend Developmentconcurrencyniofile I/OFile Lock
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.