首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 單例運行檢測:基於檔案鎖的跨平台實作

     編輯:Java 相關知識

需求場景

防止使用者重複啟動同一 Java 應用程式(如桌面客戶端、代理服務),需在啟動早期檢測是否已有實例運行,若是則提示並退出。

核心原理:檔案鎖

  • 利用 FileChannel.tryLock() 嘗試獲取**獨佔鎖**。
  • 若鎖獲取失敗(返回 null),表示另一進程已持有鎖 → 程式正在運行。
  • 鎖檔案存放於使用者家目錄(Windows)或 /usr/temp/(類 Unix),確保跨使用者隔離與寫入權限。
  • JVM 進程結束時,作業系統自動釋放檔案鎖,無需手動清理。

完整實作代碼


private static boolean isRunning() {
    boolean running = false;
    try {
        String osName = System.getProperty("os.name");
        String path;
        if (osName.contains("Windows")) {
            path = System.getProperty("user.home") + File.separator;
        } else {
            path = "/usr/temp/";
        }
        File dir = new File(path);
        if (!dir.exists()) dir.mkdirs();

        String lockFile = path + "sms.lock"; // 應用唯一標識
        RandomAccessFile raf = new RandomAccessFile(lockFile, "rw");
        FileChannel channel = raf.getChannel();
        FileLock lock = channel.tryLock(); // 非阻塞嘗試

        if (lock == null) {
            System.out.println("程式已在運行中。");
            running = true;
        }
        // 註意:此處為示範簡化,實際應將 raf/channel/lock 保持為類成員,
        // 直到程式正常退出,防止被 GC 關閉導致鎖提前釋放。
    } catch (IOException e) {
        e.printStackTrace();
    }
    return running;
}

關鍵細節與最佳實踐

1. 鎖資源生命週期管理


// 正確模式:主類持有鎖引用
public class App {
    private static FileChannel lockChannel;
    private static FileLock appLock;

    public static void main(String[] args) {
        if (acquireLock()) {
            try { runApplication(); }
            finally { releaseLock(); }
        }
    }
    private static boolean acquireLock() { /* tryLock 並保存 channel/lock */ }
    private static void releaseLock() { /* lock.release(); channel.close(); */ }
}

2. 跨平台路徑處理

  • Windows:user.home 通常為 C:\Users\Name,有寫入權限。
  • Linux/macOS:/tmp 或 /var/lock 更標準,/usr/temp 可能不存在或需 root 權限。建議使用 System.getProperty("java.io.tmpdir")。

3. 鎖檔案命名

使用應用唯一標識(如 com.myapp.Main.lock),避免不同應用衝突。

4. 替代方案對比

方案優點缺點
檔案鎖 (FileLock)跨平台、進程級、自動清理網路檔案系統 (NFS/SMB) 上行為不可靠
Socket 端口佔用簡單、網路可檢測端口衝突風險、防火牆干擾
PID 檔案傳統、易檢查殘留 PID 檔導致誤判、需手動清理
JMX/RMI 註冊管理功能豐富複雜、需額外配置

結語

檔案鎖是實現 Java 單例運行檢測的**輕量、跨平台、自清理**首選方案。關鍵在於**持有鎖引用直到程式退出**,並妥善處理跨平台路徑與異常情況。將此檢測置於 main() 最開頭,即可有效防止重複啟動帶來的資源衝突與資料損壞。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved