并发中的锁文件模式

415 查看

并发中的锁文件模式是Java企业设计模式中的一种。可以是本地锁,也可以分布式锁,看文件系统是本地还是分布式的,算是一种比较古老的方式。利用zk实现分布式锁,其实跟这个也比较类似。zk其本质是个树形结构。

代码

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
 * Subclass of RandomAccessFile that always ensures that it
 * has exclusive access to a file before opening it.
 */
public class ExclusiveRandomAccessFile extends RandomAccessFile {
    private static final String LOCK_FILE_SUFFIX = ".lck";
    private File lockFile;
    /**
     * Open the named file using a lock file to ensure
     * exclusive access.
     * @param fileName The name of the file to open.
     * @param mode This should either be "r" for read-only
     *             access or "rw" for read-write access.
     * @exception FileSharingException
     *            If there is already a lock file for the named
     *            file.
     * @exception IOException
     *            If there is a problem opening the file
     */
    public static ExclusiveRandomAccessFile openExclusive(String fileName,
                                            String mode)
            throws IOException {
        File lockFile = new File(fileName+LOCK_FILE_SUFFIX);
        //createNewFile是原子操作
        if (!lockFile.createNewFile()) {
            // lock file already exists
            throw new FileSharingException(fileName);
        } // if
        return new ExclusiveRandomAccessFile(fileName,
                mode,
                lockFile);
    } // openExclusive(String)
    /**
     * Construct a RandomAccessFile that has exclusive access
     * to the given file.
     * @param fileName The name of the file to open.
     * @param mode This should either be "r" for read-only
     *             access or "rw" for read-write access.
     * @param lockFile A file object that identifies the lock
     *                 file.
     */
    private ExclusiveRandomAccessFile(String fileName,
                                      String mode,
                                      File lockFile)
            throws IOException {
        super(fileName, mode);
        this.lockFile = lockFile;
    } // constructor(String, String)
    /**
     * Close this file.
     */
    public synchronized void close() throws IOException {
        if (lockFile!=null) {   // If file is still open
            lockFile.delete();
            lockFile = null;
            super.close();
        } // if
    } // close()
}
class FileSharingException extends IOException {
    public FileSharingException(String msg) {
        super(msg);
    } // constructor(String)
} // class FileSharingException

要点

1、检查文件如果不存在则创建,要是原子操作,使用File.createNewFile即可实现
2、锁占用过长怎么处理?或者忘记解锁怎么处理?