如何让 运行 一次只有一个应用程序实例?

How to let run only one instance of application at a time?

我正在开发一个使用 JavaFX(不是 fxml)并导出为 JAR 的 GUI 应用程序。对于慢速机器,不耐烦的用户多次点击 JAR,并启动了多个应用程序实例。

我正在寻找一种解决方案,让系统一次只能 运行 一个实例,并且如果用户在应用程序正在 运行 时再次单击,则什么也不会发生。我认为它被称为单例但不知道如何实现它。

我使用的一个简单的解决方案是,当您启动应用程序时,它会创建一个文件(我将其命名为 .lock 但您可以随意命名),除非该文件已经存在,在这种情况下,应用程序终止执行而不是创建文件。

你可以试试 JUnique。它是一个开源库,可以完全满足您的要求。将 junique-1.0.4.jar 作为库导入到您的项目中。这只是一个 10kb 的文件。

manual 巧妙地描述了如何在项目中实施它。对于 JavaFX 应用程序,实现看起来像这样:

确保将这些 类 导入到您的 main

import it.sauronsoftware.junique.AlreadyLockedException;
import it.sauronsoftware.junique.JUnique;
    public static void main(String[] args) {

        String appId = "myapplicationid";
        boolean alreadyRunning;
        try {
            JUnique.acquireLock(appId);
            alreadyRunning = false;
        } catch (AlreadyLockedException e) {
            alreadyRunning = true;
        }
        if (!alreadyRunning) {
            launch(args); // <-- This the your default JavaFX start sequence 
        }else{ //This else is optional. Just to free up memory if you're calling the program from a terminal.
            System.exit(1);
        }
    }

如果您将您的 JavaFX 代码正确地打包为一个真正的应用程序,而不是仅仅将其放入一个 jar 中,您可能会免费获得该功能,而无需所有这些黑客攻击。如果我使用 jpackage 工具将我的 JavaFX 代码打包到我的 Mac 上,结果将是一个功能齐全的 macOS 应用程序。这意味着当我在某处多次 double-click 它的图标时,只会启动一个应用程序实例。这是 Macs 上的默认行为,正确打包的 JavaFX 应用程序也遵循该规则。但是我不能说 Windows 或 Linux 上的行为是什么,因为我目前没有这样的框 运行。也许知道的人可以将此添加为评论。

您需要将您的应用程序与资源绑定。它可以是文件、端口等。 您可以在启动时更改代码以检查文件是否被锁定。下面的代码会给你一些想法

FileOutputStream foStream = new FileOutputStream("/tmp/testfile.txt");
FileChannel channel = fileOutputStream.getChannel();
FileLock lock = channel.lock();