欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

让java程序只运行一个实例

程序员文章站 2022-07-13 16:10:10
...

最近做了个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;  

   }