我知道我们可以使用flock() 在linux 中锁定一个文件。但是,NFS 驱动器可能不支持文件锁定。
我正在考虑在我的 java 代码中实现一些自定义文件锁定逻辑,以支持任何驱动器上的文件锁定。任何人都可以提出一个好的做法吗?
谢谢,
文件锁定必须由操作系统内核/文件系统驱动程序完成,除非您正在考虑更窄的范围,例如仅在单个进程的线程之间锁定。系统上的所有其他进程都无法知道与您的应用程序对话以锁定/解锁,而无需对其进行重写。当考虑像 NFS 所做的那样考虑分布式锁定时,这一点更加重要(尽管您注意到,有许多损坏的 NFS 实现做得不好)。
您可以自己创建一个新文件,用作锁定文件(以下是 Java 中的示例,因为您声明要在 Java 中实现一些自定义文件锁定逻辑):
File lockFile = new File(".filelock");
if(!lockFile.exists()){
//create lock file
boolean success = lockFile.createNewFile();
//execute some logic...
//delete lock file
lockFile.delete();
}else{
//lock file exists, cannot execute the logic that we wanted
}
Java 标准库不公开flock()
或fnctl()
直接公开。它似乎lockf()
在FileChannel/FileLocklockf()
中使用——但如果你需要确定的话,我不会指望它使用。从库的角度来看,这是一个可以更改的实现细节。
如果你真的想使用特定的 posix 功能,看看jnr-posix和相关项目。这是一个如何使用它的示例。请注意,这基本上是用 Java 编写低级 C,但这毕竟是目标,对吧?:)
// couldn't find these in jnr-posix...
// from http://linux.die.net/include/sys/file.h
/* Operations for the `flock' call. */
public static final int LOCK_EX = 2; /* Exclusive lock. */
public static final int LOCK_UN = 8; /* Unlock. */
/* Can be OR'd in to one of the above. */
public static final int LOCK_NB = 4; /* Don't block when locking. */
private static void throwErrno(String fn, Path path) throws IOException {
int err = posix.errno();
throw new IOException(fn + "() returned errno " + err + " '" + Errno.valueOf(err) + "' for " + path );
}
public int flock(Path path, int mode, boolean blocking) {
int fd = posix.open(path.toString(),
OpenFlags.O_WRONLY.intValue() | OpenFlags.O_CREAT.intValue(),
mode);
if (fd < 0) {
throwErrno("open", path);
}
int operation = LOCK_EX;
if (!blocking) {
operation |= LOCK_NB;
}
int ret = posix.flock(fd, operation);
if (ret != 0) {
throwErrno("flock", path);
}
return fd;
}
这只是最小的演示代码。我建议返回一个AutoClosable
在关闭时释放日志的。