如何实现单实例Java应用程序?
2022-08-31 11:07:31
有时我看到许多应用程序,如msn,Windows媒体播放器等是单实例应用程序(当用户在应用程序运行时执行时,不会创建新的应用程序实例)。
在C#中,我使用class来实现这一点,但我不知道如何在Java中执行此操作。Mutex
有时我看到许多应用程序,如msn,Windows媒体播放器等是单实例应用程序(当用户在应用程序运行时执行时,不会创建新的应用程序实例)。
在C#中,我使用class来实现这一点,但我不知道如何在Java中执行此操作。Mutex
我在main方法中使用以下方法。这是我见过的最简单,最健壮,侵入性最小的方法,所以我想我会分享它。
private static boolean lockInstance(final String lockFile) {
try {
final File file = new File(lockFile);
final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
final FileLock fileLock = randomAccessFile.getChannel().tryLock();
if (fileLock != null) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
fileLock.release();
randomAccessFile.close();
file.delete();
} catch (Exception e) {
log.error("Unable to remove lock file: " + lockFile, e);
}
}
});
return true;
}
} catch (Exception e) {
log.error("Unable to create and/or lock file: " + lockFile, e);
}
return false;
}
如果我相信这篇文章,由:
让第一个实例尝试在本地主机接口上打开侦听套接字。如果能够打开套接字,则假定这是要启动的应用程序的第一个实例。如果不是,则假定此应用程序的实例已在运行。新实例必须通知现有实例已尝试启动,然后退出。现有实例在收到通知后接管,并向处理操作的侦听器触发事件。
注意:Ahe在评论中提到使用可能很棘手:InetAddress.getLocalHost()
- 它在 DHCP 环境中无法按预期工作,因为返回的地址取决于计算机是否具有网络访问权限。
解决方案是打开与InetAddress.getByAddress(new byte[] {127, 0, 0, 1})的
连接;
可能与错误4435662有关。
getLocalHost
127.0.0.1
令人惊讶的是,在Linux上回归,但在Windows上却没有。
getLocalHost
127.0.0.1
该方法接收当前应用程序 PID 作为参数,并捕获从命令行调用的应用程序名称,例如,应用程序是从 path 启动的,则值变量为 “”。这样,我们将在下面代码的第17行捕获应用程序名称。
之后,我们在JVM中搜索另一个同名的进程,如果我们找到它并且应用程序PID不同,则意味着这是第二个应用程序实例。getMonitoredVMs(int processPid)
c:\java\app\test.jar
c:\\java\\app\\test.jar
JNLP 还提供单实例列表