简体   繁体   English

Java:如果我的程序实例正在运行,我该如何检测它,然后关闭旧的程序

[英]Java: If I have a instance of my program running, how do I detect that, and then close the old one(s)

I only want one instance of my program running. 我只想运行一个程序实例。 But I want it to close the older ones, if they ore open. 但如果他们开放的话,我希望它关闭旧的。

This is in Java. 这是Java。

If the application is launched using Java Web Start it can access the SingleInstanceService of the JNLP API. 如果使用Java Web Start启动应用程序,则可以访问JNLP API的SingleInstanceService。 Here is a demo. 这是一个演示。 of the SIS . SIS

You could always have a lock file, and make sure your program terminates if it can't acquire an exclusive lock on it. 您可以随时拥有一个锁定文件,并确保您的程序在无法获取其独占锁定时终止。

Reference 参考

I guess you're talking about a standalone java program, each instance running in its own JVM. 我猜你在谈论一个独立的java程序,每个实例都在自己的JVM中运行。 In that case here are the options I see for you: 在这种情况下,这是我看到的选项:

  • Set-up RMI calls between your programs (it looks a bit overkill) 在你的程序之间设置RMI调用(看起来有点矫枉过正)
  • Try cajo (I haven't tried it myself but it seems it could solve your problem) 尝试cajo (我自己没试过,但似乎它可以解决你的问题)
  • If you're on unix/linux, invoke shell script to kill existing process 如果您使用的是unix / linux,请调用shell脚本来终止现有进程
  • Use a home made solution, for example create a file with a unique name on the file system each time your program start and delete any other file present in the same directory. 使用自制解决方案,例如,每次程序启动时在文件系统上创建一个具有唯一名称的文件,并删除同一目录中存在的任何其他文件。 Then check periodically that the file attached to the current instance is still there (using a timer), if it's not, terminate the current JVM. 然后定期检查附加到当前实例的文件是否仍然存在(使用计时器),如果不存在,则终止当前JVM。

You can use a server socket address as an exclusive lock. 您可以将服务器套接字地址用作独占锁。

When your app starts, it will try to bind a server socket to a predefined address. 当您的应用程序启动时,它将尝试将服务器套接字绑定到预定义的地址。 If that fails, it means a previous instance of app is running and owning that address. 如果失败,则表示先前的app实例正在运行并拥有该地址。 Ping that address to tell the owner to exit. Ping该地址告诉所有者退出。

serverSocket = new ServerSocket(localhost:8888)
if success, 
    start ServerSocketListeningThread
else
    socket = new Socket(localhost:8888)
    socket.close();
    sleep(100);
    repeat attempt of binding server socket

ServerSocketListeningThread
    serverSocket.accept();  //block until someone connects
    System.exit(); 

It's easy to shut down your app from command line 从命令行关闭应用程序很容易

telnet localhost 8888

Just call the Exiter.isAlone() method in the main() method. 只需在Exiter.isAlone()方法中调用Exiter.isAlone() main()方法即可。 It kills the previous.(It is an implementation of the solution of Irreputable, thank) A server socket is listening on the port 8181 (in this exemple). 它杀死了前一个。(它是无声的解决方案的实现,谢谢)服务器套接字正在侦听端口8181(在这个例子中)。 If it get any request, it exists and stop jvm (System.exist()). 如果它得到任何请求,它就存在并停止jvm(System.exist())。 When u launch a new application, it try to install the socket listener. 当您启动新应用程序时,它会尝试安装套接字侦听器。 If it is ok, if the port is busy , it send a request to stop it. 如果没问题,如果端口忙,它会发送停止请求。 The method isAlone() is waiting the killing the previous is done. 方法isAlone()正在等待先前完成的查杀。 If u call it in the first line of the main(String[] s) method, u are sure the previous has been removed. 如果你在main(String [] s)方法的第一行中调用它,你就确定已经删除了前一行。

public class Exiter implements Runnable {

    private static final Exiter instance = new Exiter();
    private ServerSocket serverSocket;
    private int port = 8181;
    private boolean bStarting = true;

    private Exiter() {
        (new Thread(this)).start();
    }

    @Override
    public void run() {

        while (bStarting) {
            try {
                serverSocket = new ServerSocket(port);
                bStarting = false;
                awake();
            } catch (IOException e) {
                System.err.println("Exiter : "+e.getMessage()+"  port "+port);
                openSocketKillRequest();
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
        }
        try {
            Socket s = serverSocket.accept();// Ca bloque
            System.err.println("Kimll Request from :" + s.getRemoteSocketAddress());
            System.exit(0);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private void openSocketKillRequest() {
        try {
            System.err.println("Send request kill previous");
            Socket socket = new Socket("localhost", port);
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Exiter getInstance() {
        return instance;
    }

    private synchronized void awake(){
        notifyAll();
    }

    public synchronized boolean isAlone() {
        if(bStarting){
            try {
                wait();
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
        return true;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何修复我的 java 程序不停止运行? - How do I fix my java program not stopping running? 如何从旧实例创建新实例? - How do I create a new instance from an old one? 如何使用一个Java程序监视另一个Java程序的输出? - How do I use one Java program, to monitor another Java program's output? 如何确保只能执行我的程序的一个实例? - How do I make sure only one instance of my program can be executed? 我的Java程序中有一个错误,我认为这是一个小错误,但我不知道该怎么办? - I have an error in my Java program and I think it's a minor error but I don't know what to do? 如何在Java程序中实现“ this”? - How do I implement “this” into my Java program? 如何启用 Cloud Native Buildpacks 构建器来检测我的 Gradle Java 项目的 Java 版本? - How do I enable a Cloud Native Buildpacks builder to detect my Gradle Java project's Java version? 我如何运行已安装的Java程序? - How do I get a Java program I installed running? 如何检测我的测试是否在Jenkins环境中运行? - How do I detect my test is running on a Jenkins environment? Java:如何在打开另一个 JFrame 的同时关闭另一个? - Java: How do I close a JFrame while opening another one?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM