如何允许一次只运行一个Java程序实例?

räp*_*äph 27 java jnlp java-web-start

我需要阻止用户多次启动我的Java应用程序(WebStart Swing应用程序).因此,如果应用程序已在运行,则无法再次启动它或显示警告/再次关闭.

有没有一些方便的方法来实现这一目标?我想过阻塞一个端口或写一个文件.但希望您可以访问某些系统属性或JVM?

顺便说一句.目标平台是带有Java 1.5的Windows XP

Dav*_*ebb 35

我认为你在开始申请时打开一个端口听的建议是最好的主意.

这很容易做到,关闭应用程序时无需担心清理它.例如,如果您写入文件但有人使用任务管理器杀死进程,则该文件不会被删除.

另外,如果我没记错的话,没有简单的方法可以从JVM内部获取Java进程的PID,所以不要尝试使用PID来制定解决方案.

像这样的东西应该做的伎俩:

private static final int PORT = 9999;
private static ServerSocket socket;    

private static void checkIfRunning() {
  try {
    //Bind to localhost adapter with a zero connection queue 
    socket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1}));
  }
  catch (BindException e) {
    System.err.println("Already running.");
    System.exit(1);
  }
  catch (IOException e) {
    System.err.println("Unexpected error.");
    e.printStackTrace();
    System.exit(2);
  }
}
Run Code Online (Sandbox Code Playgroud)

此示例代码明确绑定到127.0.0.1哪个应该避免任何防火墙警告,因为此地址上的任何流量必须来自本地系统.

在选择端口时,尽量避免在众所周知的端口列表中提到的端口.理想情况下,应该在文件中使用可配置的端口,或者在发生冲突时通过命令行开关进行配置.

  • 这是一个坏主意,因为端口是按*每个系统*分配的,而不是*每个用户*。在 Windows 终端服务器、具有快速用户切换功能的 Windows、具有快速用户切换功能的 Mac 或多人登录到 UNIX 机器上,这会成为拒绝服务攻击。 (2认同)

Tom*_*ine 26

由于问题表明WebStart正在使用,显而易见的解决方案是使用javax.jnlp.SingleInstanceService.

这项服务在1.5.请注意,1.5目前是其服务终止期限的大部分时间.使用Java SE 6!