我怎样才能避免同时在同一个java项目上运行多个实例?

时间:2011-03-03 13:42:44

标签: java

我有一个java项目,作为服务器。当这个项目的一个实例运行时,我可以运行另一个实例 我怎样才能避免同时在同一个java项目上运行多个实例? (检测到其他实例时停止服务器)

4 个答案:

答案 0 :(得分:3)

import java.net.ServerSocket; 
..... 
private static final int PORT = 9999;
private static ServerSocket socket;  
public static void main(String[] args) {

    try {
        socket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }));

                {/*here write your own code taht must be run in the main*/}

    } catch (BindException e) {
        System.err.println("**********************************Already running.");
        System.exit(1);
    } catch (IOException e) {
        System.err.println("************************************Unexpected error.");
        e.printStackTrace();
        System.exit(2);
    } catch (Exception e) {
        System.err.println("************************************ Error");
        System.exit(3);
    }
}

我使用了这段代码并尝试了它

答案 1 :(得分:2)

最简单的方法是使用锁定文件,如果应用程序崩溃,这会导致问题。尝试将pid写入锁定文件,您可以检查该pid是否存在(虽然本身可能不是在包装器shell脚本中)。

如果您正在运行服务器,则无法检查端口是否已打开,或者更好的可能是已知端口上的jmx实例。

答案 2 :(得分:1)

我完全支持@vickirk - 他的方法允许服务器的第二个“不需要的”实例变为“休眠”而不是简单地终止,即定期运行以执行检查“活动”实例是否仍然实际处于活动状态/现在,如果它下降,接管。

在分布式案例中,如果要求是将单个服务器实例跨越多台计算机,则该方法仍然是找到可以物理或逻辑锁定的公共资源。为此,我个人使用一个控制数据库表,其中一个活动进程写入其PID和“心跳”,而所有其他人正在检查该“心跳”是否相当近,并且如果不是则会变为活动状态。

答案 3 :(得分:0)

您可以为app start编写简单的命令行脚本 - 该检查是在实际运行新实例之前运行的服务器。只需用wget检查网址,例如......