我想我漏掉了一些东西,但是我不知道Java中的文件锁如何工作。更确切地说 - 它是如何实现的。
在单个JVM内似乎无法获取(甚至无法尝试获取)同一文件的两个或多个锁。第一个锁将被成功获取,在尝试获取更多锁时会导致OverlappingFileLockException异常。但对于单独的进程,则适用。
我想要实现由文件系统支持的数据存储,旨在处理多个并发请求(读取和写入)。我想使用文件锁定存储中特定文件上的锁。
看来我必须在JVM级别引入另一种同步(排它),然后再对文件进行同步以避免这个异常。
有人做过类似的事情吗?
我准备了一个简单的测试用例来展示我的问题。我使用的是Mac OS X,Java 6。
在单个JVM内似乎无法获取(甚至无法尝试获取)同一文件的两个或多个锁。第一个锁将被成功获取,在尝试获取更多锁时会导致OverlappingFileLockException异常。但对于单独的进程,则适用。
我想要实现由文件系统支持的数据存储,旨在处理多个并发请求(读取和写入)。我想使用文件锁定存储中特定文件上的锁。
看来我必须在JVM级别引入另一种同步(排它),然后再对文件进行同步以避免这个异常。
有人做过类似的事情吗?
我准备了一个简单的测试用例来展示我的问题。我使用的是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();
}
}