1

我正在开发一个 Java 应用程序。而且我想防止用户同时运行同一个 Java 应用程序的多个实例。我使用 Java 的 JUnique 应用程序锁定库,效果很好。但是当它崩溃时有一个严重的问题。

如果应用程序崩溃,则无法启动应用程序,它只会返回 AlreadyLockedException。我用来锁定我的应用程序的代码如下。

public static boolean isRunning() {
    boolean alreadyRunning = false;
    try {
        JUnique.acquireLock(appId);
        alreadyRunning = false;
    } catch (AlreadyLockedException e) {
        logger.error("Unable to acquire lock. There is an instance already running");
        alreadyRunning = true;
    } catch (Throwable t) {
        logger.error("Unable to acquire lock. ", t);
    }
    return alreadyRunning;
}

释放我的锁的代码是:

public static void release() {
    try {
        JUnique.releaseLock(appId);
    } catch (Throwable t) {
        logger.error("Error releasing the lock", t);
    }
}

我可以使用 release() 方法来处理预期的崩溃。但真正的问题发生在应用程序在运行时意外崩溃时。应用程序在不释放应用程序获取的锁的情况下终止。

如果应用程序意外崩溃,我们如何释放 JUnique 锁?

4

1 回答 1

4

这是 JUnique 的设计缺陷(我在这里找到的最新版本)。根本不支持计算机崩溃的用例(BSOD,电源中断)。假设ShutdownHook总是执行(删除锁,参见JUnique.java )。该缺陷在releaseLockapi-docs 中很明显:

“请注意,一个锁只能由之前获得它的同一个 JVM 释放。如果给定的 ID 不对应于属于当前 JVM 的锁,则不会采取任何行动。”

但是没有方法forceReleaseLock(String id)反过来意味着在计算机崩溃后,应用程序将无法再启动。

在这种情况下,向用户显示带有“应用程序已在运行”消息的对话框和显示正在运行的应用程序窗口的“确定”按钮是很常见的。在这种情况下,您可以添加一个按钮“不,它不是”,然后单击:

  • 检查应用程序是否没有打开的窗口。
  • 检查是否JUnique.sendMessage返回 null。
  • 删除new File(System.getProperty("user.home"), ".junique");(LOCK_FILES_DIR,参见JUnique.java)的内容,或者不那么粗糙的类似内容。
  • 启动应用程序。
于 2014-08-29T13:13:01.207 回答