首页 > 开发 > 综合 > 正文

控制运行中的application进程实例的个数

2024-07-21 02:14:16
字体:
来源:转载
供稿:网友

    在c++中很容易实现控制应用程序只能运行一个进程实例,在c#中也很好实现,但在java中想要控制程序的实例数就是非常苦难的事情。究其原因,是因为c++和c#都是通过向windows注册表写数据来实现进程互斥,但java是跨平台的,不能用这种只能针对windows的方法来实现。

    因为java中进程之间非常独立,很少有可以共享的东西,所以只有找到可以在进程间共享的东西,才能实现进程的互斥。有两种东西可以用来实现互斥。一是socket端口,一是文件锁。因为使用socket可能会存在端口被占用的问题,而且,占用网络端口这种本来就很紧俏的资源来实现互斥也是得不偿失的。所以我们这里用第二种东西来实现进程互斥:文件锁。

    用文件锁来实现互斥还有一个好处,即可以控制进程实例的个数,比如控制只能运行三个实例或四个实例,而不是像一般程序一样紧紧只能运行一个实例。

    为了用文件锁实现进程实例数的控制,我这里写了一个instancecount类。使用方法如下:

    int count = instancecount.getinstance().getcount();//获取本程序当前已经在运行中的进程实例数。

   然后就可以根据这个count来控制实例数了,比如:

    if(count >3)system.exit(0);

    不过这里要注意一个问题,就是java应用程序是由一堆class文件组成的,如果在系统中存在这些class的多个拷贝,我认为它们是属于不同的application,即只有用同一的class文件所启动的进程才算是同一application的不同实例。这个定义如果大家不接受,可以修改我的代码以符合大家自己的定义。

此类还需要用到另一个类path,这个类在我写的另一篇文章《获取类的class文件的绝对路径 》中有介绍:

http://blog.csdn.net/youyue/archive/2005/03/22/326477.aspx

此类的源代码如下:

 * 创建日期 2005-1-26 * * todo 要更改此生成的文件的模板,请转至 * 窗口 - 首选项 - java - 代码样式 - 代码模板 */package mytools;

import java.io.file;import java.io.filenamefilter;import java.io.ioexception;import java.io.randomaccessfile;import java.nio.channels.filechannel;import java.nio.channels.filelock;

/** * 这个类可以用来获取java程序的实例数。 这里的实例是指运行同一个java程序所产生的进程实例, 而所谓“同一个”是指同一份class文件或jar文件, * 如果将这些文件复制至其他位置而重新运行所产生的实例, 不属于此类所定义的同一个java程序产生的实例。 *  * @author 由月 * @version 2005-02-01 */public class instancecount { private int count = 0;

 private static instancecount theinstance = null;

 private file filepath = null;

 private file tempfile = null;// 用来标识本实例的临时文件

 private filechannel filechannel = null;

 private filelock filelock = null;

 private randomaccessfile rafile = null;

 private instancecount() throws ioexception {// 私有的构造子,保证此类无法用new操作符来创建对象。  string path = path.getpathfromclass(this.getclass());// 获取instancecount类的class文件所在路径  this.filepath = new file(path);  this.filepath = new file(this.filepath.getparent(), "insttmp");  if (this.filepath.exists() && this.filepath.isdirectory()) {// 是否已经存在insttmp目录   getcount();  } else {   this.filepath.mkdir();  }  this.tempfile = file.createtempfile("~inst", ".tmp", this.filepath);// 创建标识本实例的临时文件  this.rafile = new randomaccessfile(this.tempfile, "rw");  this.filechannel = rafile.getchannel();// 获得该文件的filechannel对象  this.filelock = filechannel.trylock();// 给临时文件加锁,以保证进程实例的唯一性  this.tempfile.deleteonexit();  if (this.filelock != null) {   this.count++;// 新实例产生,实例总数增加1  } else {   throw new ioexception();  } }

 private void getcountandmax() {  file[] filelist = this.filepath.listfiles(new filenamefilter() {// 获取insttmp目录下的临时文件列表     public boolean accept(file dir, string name) {// 这里使用了过滤器,只获取已经被加锁了的.tmp文件的列表      try {       file tempfile = new file(dir, name);       randomaccessfile rafile = new randomaccessfile(         tempfile, "rw");       filechannel filechannel = rafile.getchannel();// 获得该文件的filechannel对象       filelock filelock = null;       if (instancecount.this.tempfile != null         && name.equals(instancecount.this.tempfile           .getname())) {       } else {        filelock = filechannel.trylock();       }       if (tempfile.isfile()         && name.endswith(".tmp")         && (filelock == null || filelock.isvalid() == false)) {        rafile.close();        return true;       } else {        filelock.release();        rafile.close();        tempfile.delete();// 将未加锁的和文件名不正确的文件删除掉        return false;       }      } catch (ioexception e) {       e.printstacktrace();       return false;      }     }    });  this.count = filelist.length; }

 /**  * 获取实例数控制对象。一个进程最多可以获取一个instancecount对象。  *   * @return 唯一的instancecount对象  */ public static instancecount getinstance() {  if (instancecount.theinstance == null) {// 保证本类在一个程序中只有一个实例   try {    instancecount instctrl = new instancecount();    return instctrl;   } catch (ioexception e) {    return null;// 如果发生io异常则返回空值   }  } else {   return instancecount.theinstance;  } }

 /**  * 获取正在运行中的实例的个数。  *   * @return 实例个数。  */ public int getcount() {  getcountandmax();  return this.count; }

 protected void finalize() {  try {   this.filelock.release();   this.filechannel.close();   this.rafile.close();   this.tempfile.delete();   this.filepath.delete();  } catch (ioexception e) {  } }

 public static void main(string[] args) {  try {   instancecount ic = instancecount.getinstance();   system.out.println(ic.getcount());   thread.sleep(5000);  } catch (exception e) {   e.printstacktrace();  } }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表