Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java FileLock blocking without exceptions; waiting on the lock

Tags:

java

I've discovered the Java File locking mechanism is a real mistake since it cannot do the 1st rule of locking - blocking on a call to lock! Unless I'm wrong - a call to lock() will throw an Exception if an application already maintains a lock on the file, which I know will be the case in my application. I've looked through some answers here and unfortunately I am not using Java 7.

Does anyone have suggestions on how I might handle waiting on an exclusive file lock without putting myself in a while(true) loop :)

EDIT after Aubin's answer (copy from comment):

What I want to do is access a large file after its been copied to a directory and then process it. My code is simple...

public boolean ifFileReady(File file) {
   boolean ready = false;
   FileLock lock = null;
   FileChannel channel = null;
   try {

      channel = new RandomAccessFile(file, "rw").getChannel();
      lock = channel.lock();
      lock.release();
      ready = true;
   }
   catch( IOException e ) {
      // Always Here
   }
   finally
   {
      if (channel != null)
         channel.close();
   }
   return ready;
}

I never block at the lock. It always throws

like image 732
jiveturkey Avatar asked Apr 12 '13 18:04

jiveturkey


2 Answers

The following code demonstrates that lock does indeed block without throwing an exception. I had a similar problem but discovered the exception was actually caused by opening the file rw when my user didn't have permission to do so.

It's a complete program; run two instances of it concurrently for the demonstration

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;

public class Test {
  public static void main(String args[]) throws Exception {
    FileChannel channel = null;
    File lockFile = new File("lock");
    System.out.println ("Opening file...");
    channel = new RandomAccessFile(lockFile, "rw").getChannel();
    System.out.println ("File open. Locking channel...");
    channel.lock();
    System.out.println ("Channel locked. Sleep for 30 seconds");
    Thread.sleep (30000);
    System.out.println ("Process terminating");
    }
}

To keep the code more consise I didn't include the unlocking, closing or exception handling (you will get a compiler warning). All the resources should be released automatically by the OS when the process exits.

like image 107
Rodney Avatar answered Oct 29 '22 02:10

Rodney


Copy of the documentation of java.nio.channels.FileChannel:

public abstract FileLock lock( long position, long size, boolean shared ) throws IOException

Acquires a lock on the given region of this channel's file.

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

Since: 1.4

like image 33
Aubin Avatar answered Oct 29 '22 03:10

Aubin