FileLock

java.nio.channels.FileLock Example

This article introduces the FileLock class and its basic usage. This article examples show using file locks with FileChannels.

The examples in this article are compiled and run in Windows OS environment. Note that Java SE 7 is required to run the code.
 
 
 
 
 
 
 

1. Introduction

FileLock is a token representing a lock on a region of a file. This is an abstract class defined in the java.nio.channels package.

1.1. Creating a file lock

A file-lock object is created when a lock is acquired on a file via one of the lock() or tryLock() methods of the FileChannel or AsynchronousFileChannel classes.

A file-lock object is initially valid. It remains valid until the lock is released by invoking the release() method, by closing the channel that was used to acquire it, or by the termination of the Java virtual machine, whichever comes first. The validity of a lock may be tested by invoking its isValid() method.

1.2. Exclusive and shared locks

A file lock is either exclusive or shared.

  • A shared lock prevents other concurrently-running programs from acquiring an overlapping exclusive lock, but does allow them to acquire overlapping shared locks.
  • An exclusive lock prevents other programs from acquiring an overlapping lock of either type.

Whether a lock is exclusive or shared may be determined by invoking its isShared() method.

1.3. Notes

  • The locks held on a particular file by a single Java virtual machine do not overlap. The overlaps() method may be used to test whether a candidate lock range overlaps an existing lock.
  • 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.

2. File Channels and Locking

The following FileChannel class methods can be used to acquire a lock on an underlying file.

The lock() methods return a FileLock. An invocation of this method will block.

  • lock() method acquires an exclusive lock on this channel’s file.
  • lock(long position, long size, boolean shared) method acquires a lock on the given region of this channel’s file. The lock may be an exclusive or of shared type.

The tryLock() methods return a FileLock or a null if the lock could not be acquired because another program holds an overlapping lock. This method does not block.

  • tryLock() method attempts to acquire an exclusive lock on this channel’s file.
  • tryLock(long position, long size, boolean shared) method attempts to acquires a lock on the given region of this channel’s file. The lock may be an exclusive or of shared type.

NOTE: See java.nio.channels.FileChannel Example for usage of file channels.

3. Examples

This examples show the usage of shared and exclusive locks in the following scenarios. File channels are used to access and lock the files.

  • A shared lock allows concurrently-running programs to acquire overlapping shared locks.
  • A shared lock prevents other concurrently-running programs from acquiring an overlapping exclusive lock.
  • An exclusive lock prevents other programs from acquiring an overlapping exclusive lock.
  • An exclusive lock prevents other programs from acquiring an overlapping shared lock.

NOTE: A data file is used in these example programs. All programs use the same file. It is to be created before running the code. The file is a text file named “examplefile.txt”. The contents (taken from the book One Hundred Years of Solitude by Gabriel Garcia Marquez) are as follows:
MANY YEARS LATER as he faced the firing squad, Colonel Aureliano Buendia was to remember that distant afternoon when his father took him to discover ice. At that time Macondo was a village of twenty adobe houses, built on the bank of a river of clear water that ran along a bed of polished stones, which were white and enormous, like prehistoric eggs.

4. Example 1

This example shows that a shared lock allows concurrently-running programs to acquire overlapping shared locks.

This example has two programs. Both programs read the same file through their respective file channels. The channels get a shared lock on the file.

The following code snippet shows the file channel acquiring the lock and verifying it.

FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true);
System.out.println("Lock acquired: " + lock.isValid());
System.out.println("Lock is shared: " + lock.isShared());

The file channel is opened to read an existing file. The file channel’s lock() method acquires a lock on the given region of this channel’s file. The lock() method parameters:

  • 0 is the position at which the locked region is to start; the begin of the file.
  • Long.MAX_VALUE specifies the size of the region to be locked; in this case the entire file.
  • true to request a shared lock.

The two methods of file lock isValid() and isShared() verify successful lock acquiring and if it is a shared lock respectively. At the end of the program the file channel’s close() method closes the channel and this also releases the lock.

Running the example:

The code for both the programs is same. The programs are run concurrently in two different terminals. Note the input file with text content must be created before the program run.

4.1. The Code

FileLockSharedRead.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class FileLockSharedRead {

    public static void main (String [] args)
            throws IOException, InterruptedException {

        Path path = Paths.get("examplefile.txt");
        FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
        System.out.println("File channel opened for read. Acquiring lock...");

        FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true);
        System.out.println("Lock acquired: " + lock.isValid());
        System.out.println("Lock is shared: " + lock.isShared());
		
        ByteBuffer buffer = ByteBuffer.allocate(20);
        int noOfBytesRead = fileChannel.read(buffer);
        System.out.println("Buffer contents: ");	

        while (noOfBytesRead != -1) {

            buffer.flip();
            System.out.print("    ");
			
            while (buffer.hasRemaining()) {
				
                System.out.print((char) buffer.get());                
            }

            System.out.println(" ");

            buffer.clear();
            Thread.sleep(1000);
            noOfBytesRead = fileChannel.read(buffer);
        }

        fileChannel.close(); // also releases the lock
        System.out.print("Closing the channel and releasing lock.");
    }
}

4.2. The Output

File channel opened for read. Acquiring lock...
Lock acquired: true
Lock is shared: true
Buffer contents:
    MANY YEARS LATER as
    he faced the firing
    squad, ....
Closing the channel and releasing lock.

From the output:

  • File channel opened for read. Acquiring lock…The file channel is open and ready to acquire the file lock.
  • Lock acquired: true. The file lock is acquired.
  • Lock is shared: true. The lock is of shared type.
  • Buffer contents: This is the content from the file being read.

From the code run, note that both programs run concurrently without blocking. Note that the output is same for both the programs.

5. Example 2

This example shows that a shared lock prevents another concurrently-running program from acquiring an overlapping exclusive lock.

This example has two programs. Both the programs access the same file using file channels. The first program reads the file using a channel with a shared lock. The second program writes (appends) to the file using a channel with exclusive lock.

The following code snippet from FileLockSharedRead program shows the file channel opened for read and acquiring the lock. Note the lock is of shared type.

FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
FileLock lock = fileChannel.lock(0, Long.MAX_VALUE, true);

The following code snippet from FileLockExclusiveWrite program shows the file channel opened for write and acquiring the lock. Note the lock is of exclusive type.

FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.APPEND);
FileLock lock = fileChannel.lock();

The file channel’s lock() method (without parameters) acquires an exclusive lock on this channel’s file. The lock is for the entire file.

Running the example:

The two programs are run concurrently in two different terminals. The FileLockSharedRead is started first, and then the FileLockExclusiveWrite. Observe that the program FileLockExclusiveWrite waits until the FileLockSharedRead releases the lock on the file.

Note the input file with text content must be created before the program run.

5.1. The Code

FileLockSharedRead.java

NOTE: The code for this program is shown in section 4. Example 1.

FileLockExclusiveWrite.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class FileLockExclusiveWrite {

    public static void main (String [] args)
            throws IOException {

        String input = "* end of file.";
        System.out.println("Input string: " + input);
        ByteBuffer buffer = ByteBuffer.wrap(input.getBytes());

        String filePath = "examplefile.txt";
        Path path = Paths.get(filePath);
        FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.WRITE,
            StandardOpenOption.APPEND);
        System.out.println("File channel opened for write. Acquiring lock...");
        fileChannel.position(fileChannel.size() - 1); // positions at the end of file

        FileLock lock = fileChannel.lock(); // gets an exclusive lock
        System.out.println("Lock is shared: " + lock.isShared());

        fileChannel.write(buffer);
        fileChannel.close(); // also releases lock
        System.out.println("Write complete. Closing the channel and releasing lock.");
        FilePrint.print(filePath);
    }
}

NOTE: The line 31 in the above code uses a program FilePrint to print the contents of a supplied text file. The program code is not shown here, but is included in the download ZIP file (see section 8. Download Java Source Code).

5.2. The Output

5.2.1. The FileLockSharedRead Output

File channel opened for read. Acquiring lock...
Lock acquired: true
Lock is shared: true
Buffer contents:
    MANY YEARS LATER as
    he faced the firing
    squad, Colonel Aurel
    iano Buend....
Closing the channel and releasing lock.

From the output note that the file lock is shared.

5.2.2. The FileLockExclusiveWrite Output

Input string: * end of file.
File channel opened for write. Acquiring lock...
Lock is shared: false
File contents:
     MANY YEARS LATER as he faced the firing squad, Colonel Aureliano Buendia ..., like prehistoric eggs.
* end of file.

From the output:

  • Input string: * end of file. This is the text to be written (appended) to the file.
  • File channel opened for write. Acquiring lock…The file channel is open for write and ready to acquire the file lock.
  • Lock is shared: false. The lock is not of shared type – it is exclusive.
  • File contents: The output shows the file contents with the text written (appended). Note the string “* end of file.” appended at the end of the file.

From the code run, note that the FileLockExclusiveWrite program waits until the FileLockSharedRead completes/releases the lock.

6. Example 3

This example shows that an exclusive lock prevents another concurrently-running program from acquiring an overlapping exclusive lock.

This example has two programs. Both programs read the same file through their respective file channels. The channels get an exclusive lock on the file.

The following code snippet from FileLockExclusiveRead program shows the file channel opened for read/write and acquiring the lock. Note the lock is of exclusive type.

FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.READ);
FileLock lock = fileChannel.lock();

Running the program:

The code for both the programs is same. The programs are run concurrently in two different terminals. Note the input file with text content must be created before the program run.

6.1. The Code

FileLockExclusiveRead.java

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class FileLockExclusiveRead {

    public static void main (String [] args)
            throws IOException, InterruptedException {

        Path path = Paths.get("examplefile.txt");
        FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ,
            StandardOpenOption.WRITE);
        System.out.println("File channel opened for read write. Acquiring lock...");

        FileLock lock = fileChannel.lock();  // gets an exclusive lock
        System.out.println("Lock is shared: " + lock.isShared());

        ByteBuffer buffer = ByteBuffer.allocate(20);
        int noOfBytesRead = fileChannel.read(buffer);
        System.out.println("Buffer contents: ");	

        while (noOfBytesRead != -1) {

            buffer.flip();
            System.out.print("    ");

            while (buffer.hasRemaining()) {
	
                System.out.print((char) buffer.get());                
            }

            System.out.println(" ");

            buffer.clear();
            Thread.sleep(1000);
            noOfBytesRead = fileChannel.read(buffer);
        }

        fileChannel.close();
        System.out.print("Closing the channel and releasing lock.");
    }
}

6.2. The Output

File channel opened for read write. Acquiring lock...
Lock is shared: false
Buffer contents:
    MANY YEARS LATER as
    he faced the firing
    squad, ....
Closing the channel and releasing lock.

From the output:

  • File channel opened for read write. Acquiring lock…The file channel is open and ready to acquire the file lock.
  • Lock is shared: false. The lock is of exclusive (not shared) type.
  • Buffer contents: This is the contents from the file being read.

From the code run, note that the second FileLockExclusiveRead program waits until the first program completes/releases the lock.

Note that the output is same for both the programs.

7. Example 4

This example shows that an exclusive lock prevents another concurrently-running program from acquiring an overlapping shared lock.

The example programs are FileLockExclusiveRead and FileLockSharedRead. These programs are already explained in previous examples 6. Example 3 and 4. Example 1 respectively.

Running the program:

The programs are run concurrently in two different terminals. The FileLockExclusiveRead is started first, and then the FileLockSharedRead. Note that the input file with text content must be created before the program run.

From the code run, note that the FileLockSharedRead program waits until the FileLockExclusiveReadprogram completes/releases the lock.

8. Download Java Source Code

This was an example of java.nio.channels.FileLock

Download
You can download the full source code of this example here: FileLockExamples.zip

Prasad Saya

Prasad Saya is a software engineer with over ten years’ experience in application development, maintenance, testing and consulting on various platforms. He is a certified Java and Java EE developer. At present his interest is in developing Java applications. He also has experience working with databases and ERP applications.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sami
Sami
5 years ago

Hi Prasad Saya, thank you for your efforts to help people like me. I have Desktop app. written in javaFX. The user search a DB to produce a report that show in tableView. I want to export that table to excel file. Everything work fine. The only issue I have is when the file is created and try to open it, there is a message telling the file is Locked by another user for editing, which is the app that created the file. When I close the app the file open without getting that message. How do I release the… Read more »

Back to top button