Я пишу программу, которая записывает в один файл из разных потоков на одном JVM и из разных JVM-процессов. Есть ли способ заблокировать файл как для потоков, так и процессов, так что независимо от того, сколько потоков/процессов пытается писать одновременно, только 1 может писать за один раз?Блокировка файлов между потоками и процессами
В настоящее время у меня есть что-то похожее на следующее, которое работает для блокировки потоков, но не для блокировки процессов. Если я попытаюсь использовать FileLock
поверх реализации ниже, появится synchronized
.
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import scripts.com.adz.commons.utils.FileUtilities;
import java.io.*;
public class Foo {
public static void main(String[] args) throws IOException {
Bar bar = new Bar();
bar.start();
while (true) {
FileUtilities.writeObjectToFile("C:\\test.html", "foo");
}
}
}
class Bar extends Thread {
@Override
public void run() {
while (true) {
try {
FileUtilities.writeObjectToFile("C:\\test.html", "bar");
} catch (IOException ignored) {}
}
}
}
class FileUtilitiess {
private static final Object _lock = new Object();
public static <T> T readObjectFromFile(File file) throws IOException, ClassNotFoundException {
synchronized (_lock) {
final byte[] bytes = FileUtils.readFileToByteArray(file);
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(bis = new ByteArrayInputStream(bytes));
return (T) ois.readObject();
} finally {
IOUtils.closeQuietly(ois);
IOUtils.closeQuietly(bis);
}
}
}
public static void writeObjectToFile(File file, Object object) throws IOException {
System.out.println("Sent object: " + object.toString());
synchronized (_lock) {
System.out.println("Writing object: " + object.toString());
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(bos = new ByteArrayOutputStream());
oos.writeObject(object);
FileUtils.writeByteArrayToFile(file, bos.toByteArray());
// - Start: For testing lock.
try {
Thread.sleep(10000);
} catch (InterruptedException ignored) {}
// - End: For testing lock.
} finally {
IOUtils.closeQuietly(oos);
IOUtils.closeQuietly(bos);
}
}
}
}
Вы имеете в виду [FileLock] (http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileLock.html)? –
FileLock не работает для нескольких потоков: «Они не подходят для управления доступом к файлу несколькими потоками на той же виртуальной машине». –
Показать свой код с помощью 'FileLock' на месте; не должно быть причин, по которым они не могут сосуществовать. Однако я чувствую, что вы используете неправильное решение для любой проблемы, которую пытаетесь решить, и, вероятно, вы получите более качественные ответы, если будете описывать проблему, а не вашу реализацию. – kdgregory