让java程序只运行一个实例
最近做了个java项目,功能完成后打包安装了,发现可以点开多个实例,因为桌面显示托盘,所以点一次就会出现一个托盘,并且系统也多了好几个javaw进程,这样的话就不能保证程序的健壮性了,所以要做一个判断让程序只运行一个实例。
要求只能运行一个实例,并且保证javaw进程只有一个,之前通过查资料发现有两种方式,一种是使用端口号控制的方式,先创建端口,运行的时候再判断端口是否被占用来判断是否启动新实例,第二种是文件锁的方式,这种方式的用法在于运行程序的时候将文件上锁,然后判断这个文件是否被锁来看是否要运行一个新实例,因为没找到合适的解决方式,所以文件锁的方式被我pass掉了,然后再看到的是使用端口号+文件的方式,这种方式的用法在于启动的时候创建一个文件,关闭的时候删掉这个文件,当然仅仅这么一个操作不能起上诉要求的,如果非法关闭的话,文件还存在就不能满足要求,只能是再加上一个端口的控制,即当端口被占用并且文件存在的情况下就停止运行新实例,否则启动一个实例,经试验这种方式可以得到满足
以下是代码:
public static void main(String[] args) throws IOException {
//创建lock.java文件
String filePath = new File("IDRCallDll").getAbsolutePath().substring(0,
new File("IDRCallDll").getAbsolutePath().lastIndexOf("\\"));
File getFile = new File(filePath + "\\" + "lock.java");
System.out.println(getFile.getPath());
//判断端口是否被占用
boolean flag=isLoclePortUsing(20520);
System.out.println(flag);
//如果文件存在并且端口被占用则退出
if (getFile.exists()&& flag) {
new MyTray().showDialog();
System.exit(0);
}
try {
Socket sock = new Socket("127.0.0.1", 20520);// 创建socket,连接20520端口
} catch (Exception e) {
System.out.println("端口被占用!");
}
final Class<?> clazz = (Class<?>) JavaCall.class;
final boolean isWindows = System.getProperty("os.name").contains(
"Windows");
final List<String> args1 = new ArrayList<String>();
args1.add(isWindows ? "javaw" : "java");
args1.add("-Xmx" + 128 + "M");
args1.add("-cp");
args1.add(System.getProperty("java.class.path"));
args1.add("-Djava.library.path="
+ System.getProperty("java.library.path"));
args1.add(clazz.getCanonicalName());
// logger.info("start " + args1.toString());
final ProcessBuilder pb = new ProcessBuilder(args1);
pb.redirectErrorStream(true);
try {
/**
* 读身份证信息程序
*/
pb.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
RandomAccessFile r = new RandomAccessFile(
filePath + "\\" + "lock.java", "rws");
FileChannel temp = r.getChannel();
FileLock fl = temp.lock();
}
/**
* 判断端口是否被占用
* @param port
* @return
*/
public static boolean isLoclePortUsing(int port){
boolean flag = true;
try {
flag = isPortUsing("127.0.0.1", port);
} catch (Exception e) {
}
return flag;
}
public static boolean isPortUsing(String host,int port) throws UnknownHostException{
boolean flag = false;
InetAddress theAddress = InetAddress.getByName(host);
System.out.println(theAddress);
try {
ServerSocket socket = new ServerSocket(port);
flag = true;
} catch (IOException e) {
System.out.println("beizhanyong");
}
return flag;
}
推荐阅读
-
解决C#程序只允许运行一个实例的几种方法详解
-
如何用idea将一个java程序,打成jar包,再用exe4j打包成.exe可执行文件,可以在任意电脑上运行
-
Windows 10环境下 java环境配置,以及运行自己的第一个程序,开启编程之旅
-
单例 - PHP程序运行的时候,既然是每一个HTTP请求对应一个数据库PDO连接对象实例
-
QT中实现程序只运行一个实例--应用程序的单例化
-
解决C#程序只允许运行一个实例的几种方法详解
-
C#实现只运行单个实例应用程序的方法(使用VB.Net的IsSingleInstance)
-
一个可以让.net程序在非WIN平台上运行的软件Mono
-
37.QT-QTSingleApplication-程序只运行一个实例
-
C# WinForm 判断程序是否已经在运行,且只允许运行一个实例,附源码