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

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

讓Java程序只運(yùn)行一個(gè)實(shí)例

2019-11-18 13:18:53
字體:
供稿:網(wǎng)友

  一個(gè)程序可以在內(nèi)存里面存在多個(gè)運(yùn)行實(shí)例,比如,你可以打開多個(gè)微軟的Word程序。但是,有些時(shí)候我們需要控制程序運(yùn)行的實(shí)例只有一個(gè),也就是說,該程序同一時(shí)刻在內(nèi)存里面運(yùn)行的只有一個(gè)實(shí)例。這樣當(dāng)這個(gè)程序在內(nèi)存中已經(jīng)存在一個(gè)運(yùn)行實(shí)例而用戶又再次運(yùn)行了該程序的時(shí)候,有兩種結(jié)果,第一種結(jié)果是結(jié)束目前的運(yùn)行實(shí)例,打開新運(yùn)行的實(shí)例;第二種就是讓新運(yùn)行的實(shí)例退出,原有的運(yùn)行實(shí)例繼續(xù)運(yùn)行。
  
  原理
  因?yàn)槿魏螘r(shí)候只有一個(gè)實(shí)例,所以在實(shí)現(xiàn)這種功能的時(shí)候必須借助只能被獨(dú)享的資源。假如我們的程序是基于某個(gè)平臺(tái)的,那么就可以借助操作系統(tǒng)的內(nèi)核對(duì)象來完成,比如Windows操作系統(tǒng)就提供了CreateMutex這個(gè)API來創(chuàng)建一個(gè)獨(dú)享的內(nèi)核對(duì)象。但是因?yàn)橐紤]平臺(tái)無關(guān),java程序的實(shí)例控制不應(yīng)該使用系統(tǒng)的內(nèi)核對(duì)象來完成,那么我們就必須找到其它的、可以獨(dú)享的資源。實(shí)際上,一臺(tái)機(jī)器無論是在什么操作系統(tǒng)上,網(wǎng)絡(luò)端口都是獨(dú)享的,也就是說基于網(wǎng)絡(luò)端口這個(gè)獨(dú)享的原理,我們可以很方便地讓我們的Java程序?qū)崿F(xiàn)在內(nèi)存里面只有一個(gè)運(yùn)行實(shí)例這個(gè)功能,而且這個(gè)功能的實(shí)現(xiàn)是與平臺(tái)無關(guān)的。
  
  實(shí)現(xiàn)
  我們先來看看第一種情況是如何實(shí)現(xiàn)的,也就是說假如系統(tǒng)中已經(jīng)存在運(yùn)行實(shí)例的話,那么結(jié)束原有的運(yùn)行實(shí)例,讓新實(shí)例運(yùn)行。這個(gè)實(shí)現(xiàn)實(shí)例控制的Java類也是一個(gè)線程,具體的實(shí)現(xiàn)如下:
  
  import java.net.*;
  public class InstanceControl extends Thread {
   public void run() {
   try{
    Socket sock = new Socket("127.0.0.1",22222);
  //創(chuàng)建socket,連接22222端口                   
   }
   catch (Exception e)
   {}
   try{
    ServerSocket server = new ServerSocket(22222);//創(chuàng)建socket,在22222端口監(jiān)聽
    server.accept(); //等待連接
    server.close(); //有連接到來,也就是說有新的實(shí)例
    System.exit(0); //這個(gè)實(shí)例退出
   }catch (Exception e)
   {
    e.PRintStackTrace();
   }
   }
  }
  
  下面這個(gè)Java程序的程序入口是沒有實(shí)例控制功能的:
  
  public class ProgramMain {
   public static void main(String argv[])
   {
   mainFrame frame = new mainFrame();
   }
  }
  
  現(xiàn)在想加入實(shí)例控制,只需要添加兩行代碼,添加后代碼如下所示:
  
  public class ProgramMain {
   public static void main(String argv[])
   {
   InstanceControl ic = new InstanceControl();
   ic.start();
   mainFrame frame = new mainFrame();
   }
  }
  
  在這個(gè)基礎(chǔ)上,要實(shí)現(xiàn)第二種情況,也就是已經(jīng)有實(shí)例運(yùn)行的情況下,新的實(shí)例退出,保持原有的運(yùn)行實(shí)例,就只需要一點(diǎn)小的改動(dòng)了。具體的實(shí)現(xiàn)如下:
  
  import java.net.*;
  public class InstanceControl2 extends Thread {
   public void run() {
   try{
    Socket sock = new Socket("127.0.0.1", 22222);//創(chuàng)建socket,連接22222端口
    System.exit(0); //連接成功,說明有實(shí)例存在,則退出
   }catch (Exception e)
   {}
   try{
    ServerSocket server = new ServerSocket(22222);//創(chuàng)建socket,連接22222端口
    while (true)
    {
    server.accept(); //接受連接請(qǐng)求
    }
   }catch (Exception e)
   {
    e.printStackTrace();
   }
   }
  }
  
  這個(gè)類的使用方法和第一種情況的那個(gè)類是一樣的,只需要在原有的代碼上加入兩行代碼即可:
  
  InstanceControl2 ic = new InstanceControl();
  ic.start();
  
  擴(kuò)展
  上面的程序也許有一個(gè)小bug,就是假如程序在開始運(yùn)行時(shí)ServerSocket監(jiān)聽的端口已經(jīng)被其它程序占用,那么程序的運(yùn)行就會(huì)受到影響。所以程序的端口應(yīng)該盡量取得大一些,在這種情況下其它程序占用這個(gè)程序使用的端口的概率是可以忽略不計(jì)的。同時(shí),還可以做兩種擴(kuò)展,第一種是把端口寫在配置文件中,可通過讀配置文件得到端口,這樣就能夠在其它程序占用目前端口的情況下改變這個(gè)程序使用的端口。還有一種是在運(yùn)行的時(shí)候用兩個(gè)InstanceControl類分別在兩個(gè)端口監(jiān)聽,只要有一個(gè)InstanceControl類得到連接就做出響應(yīng),這樣兩個(gè)端口都被其它程序占用的概率就更加的微乎其微了

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 太仆寺旗| 琼海市| 荆门市| 右玉县| 绥芬河市| 古交市| 改则县| 同江市| 西昌市| 中山市| 杭锦后旗| 商城县| 罗源县| 盘锦市| 商洛市| 侯马市| 石林| 荥经县| 新巴尔虎左旗| 安新县| 东方市| 江孜县| 南和县| 平邑县| 鲁甸县| 邢台市| 曲阳县| 潞城市| 加查县| 洞口县| 丹棱县| 白沙| 扎囊县| 绩溪县| 岗巴县| 青州市| 定结县| 钦州市| 荥经县| 德州市| 滦平县|