检查单实例 Java 程序



我有一个Java程序(带有swing gui(,我希望只有一个实例存在。如果它试图打开程序的另一个实例,我希望将当前实例置于前台。

我该怎么做?

提前谢谢。

使用 Java Web Start 启动应用程序并实现 JNLP API 的SingleInstanceService。 这是一个演示。的SingleInstanceService.

如果它试图打开程序的另一个实例,我希望将当前实例置于前台。

SingleInstanceListener的新激活(字符串[](方法中挂接它。 它将传递为新发布提供的任何参数。 现有实例可以决定如何处理新的参数(例如更改文件,添加新选项卡,忽略......

您可以使用 ShutDownHook 和锁定文件来完成,请参阅这个简单示例。

我认为这是最简单的方法...

Java 中没有 prev-instance,但您可以在 temp(或/var/run(目录中创建一个 pid 文件。(并使其File.deleteOnExit()在退出时清洁它(

要将现有窗口置于顶部,您可以通过命名管道、unix 套接字或 java 远程方法调用等方式自行通知程序。一种简单而肮脏的方法是写入一个小文件,比如$TEMP/foobar-app.bring-to-top,程序应该定期轮询这个小文件,如果它存在,将窗口带到顶部并删除这个小文件。

我猜Java无法处理信号,即kill -HUP PID可能不适用于Java应用程序。即使可以,也不是每个操作系统都有信号。

我曾经用一个套接字和一个ServerSocket做过这个:


首先,当您启动应用程序时,让 ServerSocket 侦听某个端口,例如 4004 。诀窍是检查它是否抛出IOException。如果是,则有另一个应用程序正在运行,或者该端口被另一个应用程序使用(查看此列表以了解常用端口;请注意,TCP 和 UDP 端口不会相互阻塞(,否则您可以继续启动应用程序。如果实例当前正在运行,您可能希望通过连接 TCP 套接字来通知它(这保证您的连接到达;UDP 没有(。

下面是一个示例:

ServerSocket ss = null;
try {
    ss = new ServerSocket(4004);
} catch (IOException ex0) {
    // Port either occupied by your application or a foreign one
    // -> Connect
    Socket s = null;
    try {
        s = new Socket();
    } catch (Exception ex1) {
        // Something went wrong
    }
    if (s != null) {
        // Send some singnal
    }
}
if (ss == null) {
    // Close or do something else
}

(我是根据我的记忆写的,所以有些事情可能是错的,或者可以做得更好(。

在 C# 中,通常在 Applicaiton 启动时创建互斥体。如果无法创建/获取它,则应用程序的另一个实例已在运行。不幸的是,我不能 100% 确定这在 Java 中的行为是否相同或确切的语法是什么。

希望这有帮助。

模式单调:

class SingleInstance {
private static SingleInstance instance;
public SingleInstance getInstance() {
    if (instance==null)
        instance = new SingleInstance();
    return instance;
}
private SingleInstance() {
//construct it!
}
}

最新更新