如何在没有资源警告的情况下获取FileLock?

时间:2018-06-19 20:25:35

标签: file java-8 path file-locking

我有以下代码:

try {
    final Path lock = Files.write(PATH_TO_FILE_IN_A_CONSTANT, "Executing Job", StandardOpenOption.CREATE, StandardOpenOption.WRITE);

    final RandomAccessFile raf = new RandomAccessFile(lock.toFile(), "r");
    FileLock fl = new FileInputStream(raf.getFD()).getChannel().lock(0, Long.MAX_VALUE, true);
} catch (final IOException e) {
    LOGGER.error("Error while trying to write file. ERROR: " + e.getMessage(), e);

    Runtime.getRuntime().exit(-1);
}

问题在于,由于我没有关闭RandomAccessFileInputStream,所以两个Closeable 's对象都收到警告,我没有关闭对象,并且这可能导致资源泄漏。如果我确实关闭此对象,则该文件将松开授予的锁。在执行作业时,我需要锁定文件,然后将其删除。

我可以使用SuppressWarnings "resource"注释,但是我没有这样做,而是尝试研究解决方案,但是很遗憾,我没有获得任何成功。

反正有没有获取锁而没有收到此警告?

1 个答案:

答案 0 :(得分:0)

没有IO操作,您无法实现文件锁定,并且IO操作需要确保关闭,否则编译器会抱怨。您必须调整方法以实现解决方案:

public class FileLockMaster {
    //easy way to use ThreadLocal, if the batch threads are child to this thread, set release in batch shutdownHook
    InheritableThreadLocal<Lock> lock = new InheritableThreadLocal<>(); 
    //or you can create a instance or static variable here to be set in child batch threads in shutdownHook,
    //depending on batch threads will have access to instance or not respectively


    public void acquireFileLock(){
        Path PATH_TO_FILE_IN_A_CONSTANT = null;
        byte[] Executing_Job = null;
        RandomAccessFile raf = null;
        FileLock fl = null;
        FileInputStream fStream = null;
        //or you can use try with resources with while() loop inside try block
        try {
            final Path lock = Files.write(PATH_TO_FILE_IN_A_CONSTANT, Executing_Job, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
            raf = new RandomAccessFile(lock.toFile(), "r");
            fStream = new FileInputStream(raf.getFD()); 
            fl = fStream.getChannel().lock(0, Long.MAX_VALUE, true);

            /**
             * create batch threads here or outside to complete the job
             */

        } catch (final IOException e) {
            LOGGER.error("Error while trying to write file. ERROR: " + e.getMessage(), e);
            Runtime.getRuntime().exit(-1);
        } finally{
            try {
                while (true) {
                    if (this.lock.get().release) {
                        raf.close();
                        fStream.close();
                        fl.close();
                        break;
                    }
                }
            } catch (Exception e){
                //ignore
            }
    }
}

class Lock{
    boolean release;
}