Думаю, я что-то упустил, но не могу понять, как работают блокировки файлов в Java.Чтобы быть более точным - как это реализовано.
Кажется, я не могу получить (даже не могу попытаться получить) две или более блокировки для одного и того же файла в одной JVM.Первая блокировка будет успешно получена, все дальнейшие попытки получить больше блокировок приведут к исключению OverlapingFileLockException.Тем не менее это работает для отдельных процессов.
Я хочу реализовать хранилище данных с файловой системой, которое предназначено для работы с несколькими одновременными запросами (как чтение, так и запись).Я хочу использовать блокировки файлов для блокировки определенных файлов в хранилище.
Похоже, мне нужно ввести еще одну синхронизацию (эксклюзивную) на уровне 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();
}
}