Java没有提供这样的机制。从操作系统的观点来看,一个启动的Java Application仅仅是一
个JVM的运行实例。运行相同Application的两个实例,仅仅是运行两个无关的JVM。
只有让多个运行实例之间有一个既定的通讯机制就可以保证只有一个实例运行。
方案1:使用Java的加锁文件机制,idea相当简单,让运行实例通过java.nio.channels.FileLock获得一个"well-known"文件的互斥锁。
import java.io.*;
import java.nio.channels.*;
public class OneInstance_1 {
public static void main(String[] args) throws Exception {
FileLock lck = new FileOutputStream("C:\\flagFile").getChannel().tryLock();
if(lck == null) {
System.out.println("A previous instance is already running....");
System.exit(1);
}
System.out.println("This is the first instance of this program...");
// Do some work here.....
}
}
问题:平台相关
方案2:使用java.net.ServerSocket
import java.io.*;
import java.net.*;
public class OneInstance_2 {
private static ServerSocket listenerSocket;
public static void main(String[] args) {
try {
listenerSocket = new ServerSocket(2004);
//At this point, no other socket may listen on port 2004.
} catch(java.net.BindException e) {
System.err.println("A previous instance is already running....");
System.exit(1);
} catch(final IOException e) { // an unexpected exception occurred
System.exit(1);
}
// Do some work here.....
}
}
问题:打开服务端口可能会受到防火墙的影响;可能和别的端口冲突。
方案3:使用File.createNewFile() and File.deleteOnExit()
import java.io.*;
public class OneInstance_3 {
public static void main(String[] args) throws Exception {
File flagFile = new File("C:\\flagFile");
if(false == flagFile.createNewFile()) {
System.out.println("A previous instance is already running....");
System.exit(1);
}
flagFile.deleteOnExit();
System.out.println("This is the first instance of this program...");
// Do some work here.....
}
}
来源:·BBS 水木清华站 smth.org·[FROM: 202.108.130.*]
问题:文件可能因为某些原因不能被删除,即使利用Runtime.addShutdownHook()也有可能产生这种情况。