【问题标题】:JUnique locked application doesn't run if the application crashes如果应用程序崩溃,JUnique 锁定的应用程序不会运行
【发布时间】:2014-08-29 08:40:01
【问题描述】:

我正在开发一个 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 锁?

【问题讨论】:

  • 定义“崩溃”。该文档指出,锁“将在 JVM 停止时自动释放”。此外,打印并发布该AlreadyLockedException 的堆栈跟踪。
  • @chrylis,没错,它释放了锁,但是如果其他程序也在运行 JVM,那么 JVM 不会停止。即使我的应用程序崩溃,JVM 中的锁仍然存在。
  • “其他程序”是什么意思?听起来你不明白 Java 程序的启动是如何工作的。
  • @chrylis,我知道 java 程序是如何工作的。当我运行我的应用程序并且如果它崩溃时,它会停止 JVM,并且再次运行新实例没有问题。但是,如果我的应用程序在我使用 ecilpse 时崩溃,它会以某种方式在 JVM 中保持活动状态,因为 Eclipse 仍在使用 JVM。在我关闭 Eclipse 之前,应用程序无法再次启动。

标签: java multithreading swing uncaughtexceptionhandler


【解决方案1】:

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

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

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

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

  • 检查应用程序是否没有打开的窗口。
  • 检查 JUnique.sendMessage 是否返回 null。
  • 删除new File(System.getProperty("user.home"), ".junique"); 的内容(LOCK_FILES_DIR,请参阅JUnique.java),或不那么粗糙的类似内容。
  • 启动应用程序。

【讨论】:

  • 我编辑了答案并添加了一些代码来解决我的问题。谢谢范奥克尔。 @MadProgrammer 感谢您的建议。
  • @Crawler 我不认为添加UncaughtExceptionHandler 可以改善任何事情:JUnique 注册的ShutdownHook 已经确保在应用程序/JVM 停止之前移除锁(不会崩溃)。
  • 在我的例子中,JUnique 锁不会在应用程序崩溃时释放,所以我必须在 UncaughtExceptionHandler 中显式调用 releaseLock()。如果我的应用程序崩溃,我不想停止 JVM。最后,通过调用 uncaughtException 方法,在关闭钩子中处理未捕获的异常的方式与在任何其他线程中相同。您的信息很好,但 UncaughtExceptionHandler 成功了。
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2015-09-26
  • 1970-01-01
  • 1970-01-01
  • 2020-12-22
  • 2015-10-29
相关资源
最近更新 更多