Linux File Locking in Java

放肆的年华 提交于 2019-12-08 05:40:17

问题


I know we can lock a file in linux using flock(). However, NFS drive might not support file lock.

I am thinking to implement some custom file lock logic in my java code, to support file lock on any drive. Can anyone suggest a good practice?

Thanks,


回答1:


File locking must be done by the operating system kernel / file system drivers, unless you're thinking of a narrower scope like just locking between the threads of a single process. There's no way all the other processes on the system will know to talk to your application to lock/unlock without them being rewritten to do so. This is even more significant when thinking about distributed locking like what NFS does (although as you note, there are many broken NFS implementations that don't do it well).




回答2:


You can create a new file yourself which you use as a lockfile (the following is an example in Java since you stated that you wanted to implement some custom file lock logic in 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
}



回答3:


The Java Standard Library does not expose flock() or fnctl() directly. It seems to use lockf() in FileChannel/FileLock - but I wouldn't count on it using lockf() if you need to be sure. From the libraries point of view, this is an implementation details that can change.

If you actually want to use the specific posix function, take a look at jnr-posix and related projects. Here's an example how you could use it. Beware, this is basically writing low-level C in Java, but that's the goal after all, right? :)

// 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;
}

This is just minimal demo code. I would recommend to return an AutoClosable that releases the log when closed.



来源:https://stackoverflow.com/questions/12537803/linux-file-locking-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!