1

我知道我们可以使用flock() 在linux 中锁定一个文件。但是,NFS 驱动器可能不支持文件锁定。

我正在考虑在我的 java 代码中实现一些自定义文件锁定逻辑,以支持任何驱动器上的文件锁定。任何人都可以提出一个好的做法吗?

谢谢,

4

3 回答 3

3

文件锁定必须由操作系统内核/文件系统驱动程序完成,除非您正在考虑更窄的范围,例如仅在单个进程的线程之间锁定。系统上的所有其他进程都无法知道与您的应用程序对话以锁定/解锁,而无需对其进行重写。当考虑像 NFS 所做的那样考虑分布式锁定时,这一点更加重要(尽管您注意到,有许多损坏的 NFS 实现做得不好)。

于 2012-09-21T20:45:44.430 回答
2

您可以自己创建一个新文件,用作锁定文件(以下是 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
}
于 2012-09-21T20:44:49.123 回答
1

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在关闭时释放日志的。

于 2016-04-21T14:42:01.367 回答