I guess I miss something, but I cannot understand how file locks work in Java. To be more exact - how it is implemented.
It seems I cannot acquire (even cannot attempt acquiring) two or more locks for the same file inside single JVM. First lock will be successfully acquired, all further attempts to acquire more locks will result in OverlapingFileLockException. Nevertheless it works for separate processes.
I want to implement data-storage backed by file-system which is intended to work with multiple concurrent requests (both read and write). I want to use file locks to lock on particular files in the storage.
It seems that I have to introduce one more synchronization (exclusive) on JVM-level and only then sync on files to avoid this exception.
Did anyone do anything like that?
I prepared simple test case to show what my problem is. I use Mac OS X, Java 6.
import junit.framework.*;
import javax.swing.*;
import java.io.*;
import java.nio.channels.*;
/**
* Java file locks test.
*/
public class FileLocksTest extends TestCase {
/** File path (on Windows file will be created under the root directory of the current drive). */
private static final String LOCK_FILE_PATH = "/test-java-file-lock-tmp.bin";
/**
* @throws Exception If failed.
*/
public void testWriteLocks() throws Exception {
final File file = new File(LOCK_FILE_PATH);
file.createNewFile();
RandomAccessFile raf = new RandomAccessFile(file, "rw");
System.out.println("Getting lock...");
FileLock lock = raf.getChannel().lock();
System.out.println("Obtained lock: " + lock);
Thread thread = new Thread(new Runnable() {
@Override public void run() {
try {
RandomAccessFile raf = new RandomAccessFile(file, "rw");
System.out.println("Getting lock (parallel thread)...");
FileLock lock = raf.getChannel().lock();
System.out.println("Obtained lock (parallel tread): " + lock);
lock.release();
}
catch (Throwable e) {
e.printStackTrace();
}
}
});
thread.start();
JOptionPane.showMessageDialog(null, "Press OK to release lock.");
lock.release();
thread.join();
}
/**
* @throws Exception If failed.
*/
public void testReadLocks() throws Exception {
final File file = new File(LOCK_FILE_PATH);
file.createNewFile();
RandomAccessFile raf = new RandomAccessFile(file, "r");
System.out.println("Getting lock...");
FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true);
System.out.println("Obtained lock: " + lock);
Thread thread = new Thread(new Runnable() {
@Override public void run() {
try {
RandomAccessFile raf = new RandomAccessFile(file, "r");
System.out.println("Getting lock (parallel thread)...");
FileLock lock = raf.getChannel().lock(0, Long.MAX_VALUE, true);
System.out.println("Obtained lock (parallel thread): " + lock);
lock.release();
}
catch (Throwable e) {
e.printStackTrace();
}
}
});
thread.start();
JOptionPane.showMessageDialog(null, "Press OK to release lock.");
lock.release();
thread.join();
}
}
Yes, you can run multiple JVM's on a single machine. Sun packages the tools to run the jvm in a few different ways. Usually, you either have a java development kit (jdk) or java standard edition (jse) installed as the default.
A token representing a lock on a region of a file. A file-lock object is created each time a lock is acquired on a file via one of the lock or tryLock methods of the FileChannel class, or the lock or tryLock methods of the AsynchronousFileChannel class. A file-lock object is initially valid.
Yes,you can install more than one jvm in your PC, because OS loads an instance of jvm (not whole jvm) in RAM. We can call different jvm like JDK 1.4 or JDK 1.6 by setting its path. Multiple JRE (Java Runtime Enviroment) is very possible. Multiple number of JVMs can run on a single machine.
From the Javadoc:
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.
You can only acquire a lock once per file. Locks are not re-entrant AFAIK.
IMHO: Using files to communicate between process is a very bad idea. Perhaps you will be able to get this to work reliably, let me know if you can ;)
I would have one and only one thread read/write in only one process.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With