java鎖系列---分佈式時的文件鎖FileLock(排他鎖)

package com.sm.jboss;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.concurrent.CountDownLatch;

/**
 * 〈一句話功能簡述〉<br>
 *     文件鎖
 *
 * @author 19039209
 * @date 2019/12/2
 * @see [相關類/方法](可選)
 * @since [產品/模塊版本] (可選)
 */
public class FileLockTest {

    private static final Logger LOG = LoggerFactory.getLogger(FileLockTest.class.getName());

    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(1);
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch.await();
                    LOG.info("t1線程啓動...");
                    FileLock fileLock = FileLockTest.tryLock();
                    fileLock.release();
                    fileLock.channel().close();
                    fileLock = null;
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    countDownLatch.await();
                    LOG.info("t2線程啓動...");
                    FileLock fileLock = FileLockTest.tryLock();
                    fileLock.release();
                    fileLock.channel().close();
                    fileLock = null;
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();
        countDownLatch.countDown();
    }

	// 取自hadoop源碼: org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory#lock
    public static FileLock tryLock() throws IOException {
        boolean deletionHookAdded = false;
        File lockF = new File("C:\\Users\\19039209\\Desktop\\數字簽名\\test.lock");
        if (!lockF.exists()) {
            lockF.deleteOnExit();
            deletionHookAdded = true;
        }
        RandomAccessFile file = new RandomAccessFile(lockF, "rws");
        String jvmName = ManagementFactory.getRuntimeMXBean().getName();
        FileLock res = null;
        try {
            res = file.getChannel().tryLock();
            if (null == res) {
                LOG.error("Unable to acquire file lock on path {}", lockF);
                throw new OverlappingFileLockException();
            }
            file.write(jvmName.getBytes("UTF-8"));
            LOG.info("Lock on {} acquired by nodename {}", lockF, jvmName);
        } catch(OverlappingFileLockException oe) {
            // Cannot read from the locked file on Windows.
            String lockingJvmName = System.getProperty("os.name").startsWith("Windows") ? "" : (" " + file.readLine());
            LOG.error("It appears that another node {} has already locked the "
                    + "storage directory: {}", lockingJvmName, "root", oe);
            file.close();
            return null;
        } catch(IOException e) {
            LOG.error("Failed to acquire lock on {}. If this storage directory is"
                    + " mounted via NFS, ensure that the appropriate nfs lock services"
                    + " are running.", lockF, e);
            file.close();
            throw e;
        }
        if (!deletionHookAdded) {
            // If the file existed prior to our startup, we didn't
            // call deleteOnExit above. But since we successfully locked
            // the dir, we can take care of cleaning it up.
            lockF.deleteOnExit();
        }
        return res;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章