Prevent launching multiple instances of a java application

前端 未结 10 2051
你的背包
你的背包 2020-12-03 03:19

I want to prevent the user from running my java application multiple times in parallel.

To prevent this, I have created a lock file when am opening the application,

相关标签:
10条回答
  • 2020-12-03 03:28

    Creating a server socket, bounds to a specific port with a ServerSocket instance as the application starts is a straight way.
    Note that ServerSocket.accept() blocks, so running it in its own thread makes sense to not block the main Thread.

    Here is an example with a exception thrown as detected :

    public static void main(String[] args) {       
        assertNoOtherInstanceRunning();
        ...     // application code then        
    }
    
    public static void assertNoOtherInstanceRunning() {       
        new Thread(() -> {
            try {
                new ServerSocket(9000).accept();
            } catch (IOException e) {
              throw new RuntimeException("the application is probably already started", e);
            }
        }).start();       
    }
    
    0 讨论(0)
  • 2020-12-03 03:29

    You could use a FileLock, this also works in environments where multiple users share ports:

    String userHome = System.getProperty("user.home");
    File file = new File(userHome, "my.lock");
    try {
        FileChannel fc = FileChannel.open(file.toPath(),
                StandardOpenOption.CREATE,
                StandardOpenOption.WRITE);
        FileLock lock = fc.tryLock();
        if (lock == null) {
            System.out.println("another instance is running");
        }
    } catch (IOException e) {
        throw new Error(e);
    }
    

    Also survives Garbage Collection. The lock is released once your process ends, doesn't matter if regular exit or crash or whatever.

    0 讨论(0)
  • 2020-12-03 03:32

    Similar discussion is at http://www.daniweb.com/software-development/java/threads/83331

    Bind a ServerSocket. If it fails to bind then abort the startup. Since a ServerSocket can be bound only once, only single instsances of the program will be able to run.

    And before you ask, no. Just because you bind a ServerSocket, does not mean you are open to network traffic. That only comes into effect once the program starts "listening" to the port with accept().

    0 讨论(0)
  • 2020-12-03 03:44

    I see two options you can try:

    1. Use a Java shutdown hook
    2. Have your lock file hold the main process number. The process should exist when you lanuch another instance. If it's not found in your system, you can assume that the lock can be dismissed and overwritten.
    0 讨论(0)
  • 2020-12-03 03:45

    You could write the process id of the process that created the lock file into the file. When you encounter an existing lock file, you do not just quit, but you check if the process with that id is still alive. If not, you can go ahead.

    0 讨论(0)
  • 2020-12-03 03:46

    You can create a Server socket like

           new ServerSocket(65535, 1, InetAddress.getLocalHost());
    

    at very beginning of your code. Then if AddressAlreadyInUse exception caught in main block you can display the appropriate message.

    0 讨论(0)
提交回复
热议问题