I'm writing a program that writes to a single file from both different threads on the same JVM and from different JVM's/processes. Is there a way to lock a file for both threads and processes, so that no matter how many threads/processes are trying to write at the same time, only 1 can write at a time?
Currently I have something similar to the following which works for locking threads, but not for blocking processes. If I try using FileLock
on top of the implementation below it appears the synchronized
stops working.
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);
}
}
}
}
See FileLock
javadoc:
File locks are held on behalf of the entire Java virtual machine.
That means that on the OS level different threads of your application will have the same right to access the locked region.
To lock the file access from different threads you have to encapsulate your file IO code and to enforce synchronized execution.
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