国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

控制運行中的application進程實例的個數(shù)

2024-07-21 02:14:16
字體:
供稿:網(wǎng)友

    在c++中很容易實現(xiàn)控制應(yīng)用程序只能運行一個進程實例,在c#中也很好實現(xiàn),但在java中想要控制程序的實例數(shù)就是非常苦難的事情。究其原因,是因為c++和c#都是通過向windows注冊表寫數(shù)據(jù)來實現(xiàn)進程互斥,但java是跨平臺的,不能用這種只能針對windows的方法來實現(xiàn)。

    因為java中進程之間非常獨立,很少有可以共享的東西,所以只有找到可以在進程間共享的東西,才能實現(xiàn)進程的互斥。有兩種東西可以用來實現(xiàn)互斥。一是socket端口,一是文件鎖。因為使用socket可能會存在端口被占用的問題,而且,占用網(wǎng)絡(luò)端口這種本來就很緊俏的資源來實現(xiàn)互斥也是得不償失的。所以我們這里用第二種東西來實現(xiàn)進程互斥:文件鎖。

    用文件鎖來實現(xiàn)互斥還有一個好處,即可以控制進程實例的個數(shù),比如控制只能運行三個實例或四個實例,而不是像一般程序一樣緊緊只能運行一個實例。

    為了用文件鎖實現(xiàn)進程實例數(shù)的控制,我這里寫了一個instancecount類。使用方法如下:

    int count = instancecount.getinstance().getcount();//獲取本程序當(dāng)前已經(jīng)在運行中的進程實例數(shù)。

   然后就可以根據(jù)這個count來控制實例數(shù)了,比如:

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

    不過這里要注意一個問題,就是java應(yīng)用程序是由一堆class文件組成的,如果在系統(tǒng)中存在這些class的多個拷貝,我認(rèn)為它們是屬于不同的application,即只有用同一的class文件所啟動的進程才算是同一application的不同實例。這個定義如果大家不接受,可以修改我的代碼以符合大家自己的定義。

此類還需要用到另一個類path,這個類在我寫的另一篇文章《獲取類的class文件的絕對路徑 》中有介紹:

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

此類的源代碼如下:

 * 創(chuàng)建日期 2005-1-26 * * todo 要更改此生成的文件的模板,請轉(zhuǎn)至 * 窗口 - 首選項 - 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程序的實例數(shù)。 這里的實例是指運行同一個java程序所產(chǎn)生的進程實例, 而所謂“同一個”是指同一份class文件或jar文件, * 如果將這些文件復(fù)制至其他位置而重新運行所產(chǎn)生的實例, 不屬于此類所定義的同一個java程序產(chǎn)生的實例。 *  * @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;// 用來標(biāo)識本實例的臨時文件

 private filechannel filechannel = null;

 private filelock filelock = null;

 private randomaccessfile rafile = null;

 private instancecount() throws ioexception {// 私有的構(gòu)造子,保證此類無法用new操作符來創(chuàng)建對象。  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()) {// 是否已經(jīng)存在insttmp目錄   getcount();  } else {   this.filepath.mkdir();  }  this.tempfile = file.createtempfile("~inst", ".tmp", this.filepath);// 創(chuàng)建標(biāo)識本實例的臨時文件  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++;// 新實例產(chǎn)生,實例總數(shù)增加1  } else {   throw new ioexception();  } }

 private void getcountandmax() {  file[] filelist = this.filepath.listfiles(new filenamefilter() {// 獲取insttmp目錄下的臨時文件列表     public boolean accept(file dir, string name) {// 這里使用了過濾器,只獲取已經(jīng)被加鎖了的.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; }

 /**  * 獲取實例數(shù)控制對象。一個進程最多可以獲取一個instancecount對象。  *   * @return 唯一的instancecount對象  */ public static instancecount getinstance() {  if (instancecount.theinstance == null) {// 保證本類在一個程序中只有一個實例   try {    instancecount instctrl = new instancecount();    return instctrl;   } catch (ioexception e) {    return null;// 如果發(fā)生io異常則返回空值   }  } else {   return instancecount.theinstance;  } }

 /**  * 獲取正在運行中的實例的個數(shù)。  *   * @return 實例個數(shù)。  */ 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();  } }}
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 广丰县| 万全县| 江安县| 金堂县| 桃园县| 台南县| 进贤县| 九龙县| 漯河市| 潜江市| 吐鲁番市| 中西区| 睢宁县| 益阳市| 夹江县| 布尔津县| 东乌| 庆阳市| 正安县| 新田县| 卢湾区| 鸡东县| 历史| 龙海市| SHOW| 英山县| 离岛区| 库伦旗| 九江县| 蒙城县| 博爱县| 施甸县| 嘉善县| 东宁县| 广西| 南宁市| 南澳县| 罗平县| 梓潼县| 故城县| 济宁市|