Java: 如何创建一个仅在其实例不存在时启动并在实例存在时调用该实例的应用程序?

Java: How can I create an application that will only start if an instance of it doesn't exist and call the instance if it does exist?

我正在尝试使用 Java 创建一个程序,该程序一次只能有一个 运行 实例。 我正在使用 Sockets 和 ServerSockets 来尝试实现这一点。

该程序的工作原理是:

main 方法会检查是否有任何参数被传递,它会尝试将第一个参数写入服务器,如果失败则意味着这是唯一的 运行 实例,所以它将打开 ServerSocket,然后启动框架。如果它没有失败,那么应用程序已经 运行 所以它应该发送字符串并且另一个实例应该能够读取它并处理它。

主要方法如下:

public static void main(String[] args) {
    String fileName = null;
    if (args.length >= 1) {
        fileName = args[0];
    }
    if (Singleton.sendSignal(fileName)) {
        Frame.getFrame().open(fileName);
        Singleton.checkInput();
    }
}

这是服务器 class:

public class Singleton {
    private static final int portNumber = 4243;
    private static ServerSocket serverSocket;
    private static Socket clientSocket;
    private static Socket echoSocket;

    public static boolean sendSignal() {
        try {
            echoSocket = new Socket(InetAddress.getLocalHost().getHostName(), portNumber);
            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            out.write("Open\n");
            out.close();
            close();
            return false;
        } catch (Exception e) {
            close();
            return true;
        }
    }

    public static void checkInput() {
        try {
            renewReader();
        } catch (Exception e) {
            close();
        }
    }

    public static void renewReader() throws Exception {
        serverSocket = new ServerSocket(portNumber);
        clientSocket = serverSocket.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String inputLine = in.readLine();
        if (inputLine.equals("Open")) {
            Widget.getInstance().setVisible(true);
        }
        close();
        renewReader();
    }

    public static void close() {
        try {
            serverSocket.close();
        } catch (Exception e) {
        }
        try {
            clientSocket.close();
        } catch (Exception e) {
        }
        try {
            echoSocket.close();
        } catch (Exception e) {
        }
    }

}

虽然这段代码有一半有效(一次只运行一个实例),但只有第一组数据被传递,然后程序停止读取。如何让套接字监听直到程序关闭?

我是你的 checkInput() 方法,你在这里接受客户端连接一次。尝试这样的事情:

public static void checkInput() 
{   
     //do something here
     serverSocket = new ServerSocket(portNumber);
     //wait for request from client.
     Socket clientSocket = serverSocket.accept();
     //
     // do your processing here

     // call checkInput method again.
     checkInput();
}

一旦另一个实例启动,服务器将接受请求,进行处理,然后再次开始等待更多请求(为此我们再次调用了 cehckInput)。

也在您的 main() 中添加:

public static void main(String[] args) 
{
    String fileName = null;
    if (args.length >= 1) {
        fileName = args[0];
    }
    if (Singleton.sendSignal(fileName)) 
    {
        Frame.getFrame().open(fileName);

        // start the server in a thread so that main method can continue on
        new Thread()
        {
           public void run()
           {
                Singleton.checkInput();
           }
        }.start();
    }

    // do your other tasks.
}

在程序终止时,您的套接字将自动关闭。此外,如果你想明确关闭套接字,你可以添加一个关闭钩子来关闭它。 一个简单的钩子看起来像这样。

Runtime.getRuntime().addShutdownHook(your thread that will close sockets);