I've noticed that java.io
and java.nio
implementations of random access files differ slightly with respect to how FileLocks
are handled.
It appears as though (on Windows) java.io
gives you a mandatory file lock and java.nio
gives you an advisory file lock upon requesting it respectively. A mandatory file lock means that the lock holds for all processes and an advisory holds for well behaving processes that follow the same locking protocol.
If I run the following example, I'm able to delete the *.nio
file manually, while *.io
file refuses to be deleted.
import java.io.*;
import java.lang.management.ManagementFactory;
import java.nio.*;
import java.nio.channels.*;
import java.nio.file.*;
public class NioIoLock {
public static void main(String[] args) throws IOException, InterruptedException {
String workDir = System.getProperty("user.dir");
FileChannel channelIo, channelNio;
FileLock lockIo, lockNio;
// use io
{
String fileName = workDir
+ File.separator
+ ManagementFactory.getRuntimeMXBean().getName()
+ ".io";
File lockFile = new File(fileName);
lockFile.deleteOnExit();
RandomAccessFile file = new RandomAccessFile(lockFile, "rw");
channelIo = file.getChannel();
lockIo = channelIo.tryLock();
if (lockIo != null) {
channelIo.write(ByteBuffer.wrap("foobar".getBytes("UTF-8")));
}
}
// use nio
{
Path workDirPath = Paths.get(workDir);
Path file = workDirPath.resolve(
Paths.get(ManagementFactory.getRuntimeMXBean().getName() + ".nio"));
// open/create test file
channelNio = FileChannel.open(
file, StandardOpenOption.READ, StandardOpenOption.WRITE,
StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE);
// lock file
lockNio = channelNio.tryLock();
if (lockNio != null) {
channelNio.write(ByteBuffer.wrap("foobar".getBytes("UTF-8")));
}
}
// do not release locks for some time
Thread.sleep(10000);
// release io lock and channel
if (lockIo != null && lockIo.isValid()) {
lockIo.release();
}
channelIo.close();
// release nio lock and channel
if (lockNio != null && lockNio.isValid()) {
lockNio.release();
}
channelNio.close();
}
}
Is there a reason for this? Are these two even considered as alternatives or are they meant to coexist indefinitely?
SYNC, DSYNC
to the nio version make a difference? Then it would have been a performance consideration. – LibrateSYNC, DSYNC
makes no difference – Eskridge