<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks
    很巧合,今天恰好有朋友寫信與我討論這個問題,他是從網(wǎng)上看到關(guān)于這個問題的一篇文章,該文章提出使用socket來解決該問題。下面是我回信中的一些片斷:

    關(guān)于讓Java程序只運行一個實例的問題,其實質(zhì)是JVM之間通信的問題,因此自然會想到使用Socket來傳遞信號,但就像文章中提到的那樣,如果程序在開始運行時ServerSocket監(jiān)聽的端口已經(jīng)被其它程序占用,那么程序的運行就會受到影響。而且我個人認為僅僅為了判斷程序運行的實例而開一個端口來偵聽,有點殺雞用牛刀的感覺。
    我這里有一個方案可供選擇,其原理是使用文件鎖來鎖定一個代表程序運行實例的文件,當程序啟動時,首先鎖定該文件,后繼啟動的實例一旦發(fā)現(xiàn)該文件已被鎖定則提示出錯信息。(為什么不直接使用文件而是使用文件鎖來判斷呢?即:在程序啟動的時候生成一個文件而在程序退出時刪除這個文件,只要判斷該文件的存在與否就可以判斷實例的運行情況。這是因為我們不能確保刪除文件的操作一定能被執(zhí)行到,程序是可能被強制關(guān)閉或異常退出的,而文件鎖不同,它是作為系統(tǒng)資源分配給JVM的,一旦JVM當?shù)?,其資源會一并被操作系統(tǒng)回收,因此對文件的鎖定也會被消除。)

    下面是該方案的源碼。

    import?java.nio.channels.*;
    import?java.io.*;
    import?javax.swing.JOptionPane;

    //應(yīng)用實例控制類
    public?class?InstanceControl
    {
    ??FileLock?lock
    =null;
    ??
    //判斷該應(yīng)用是否已啟動
    ??public?boolean?isRunning()
    ??{
    ????
    try
    ????{
    ??????
    //獲得實例標志文件
    ??????File?flagFile=new?File("instance");
    ??????
    //如果不存在就新建一個
    ??????if(!flagFile.exists())flagFile.createNewFile();
    ??????
    //獲得文件鎖
    ??????lock=new?FileOutputStream("instance").getChannel().tryLock();
    ??????
    //返回空表示文件已被運行的實例鎖定
    ??????if(lock==null)return?false;
    ????}
    catch(Exception?ex){ex.printStackTrace();}
    ????
    return?true;
    ??}

    ??
    public?static?void?main(String[]?args)
    ??{
    ????InstanceControl?ic
    =new?InstanceControl();
    ????
    if(ic.isRunning())
    ??????JOptionPane.showMessageDialog(
    null,"已存在該程序的實例!","提示",JOptionPane.OK_OPTION);
    ????
    else
    ??????MainClass.main(args);????????????
    ??}
    }

    下面是這篇文章的原文


    ?? 讓Java程序只運行一個實例??????????????????????????????????????????????????????????????
    ????????????????????????????????????????????出自:http://developer.ccidnet.com 梁邦勇 2003年01月12日 18:04????????????????????????????????????????????
    一個程序可以在內(nèi)存里面存在多個運行實例,比如,你可以打開多個微軟的Word程序。但是,有些時候我們需要控制程序運行的實例只有一個,也就是說,該程序同一時
    刻在內(nèi)存里面運行的只有一個實例。這樣當這個程序在內(nèi)存中已經(jīng)存在一個運行實例而用戶又再次運行了該程序的時候,有兩種結(jié)果,第一種結(jié)果是結(jié)束目前的運行實??
    例,打開新運行的實例;第二種就是讓新運行的實例退出,原有的運行實例繼續(xù)運行。????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???????????????????????????????????????????????????????????????????????? 原理????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    因為任何時候只有一個實例,所以在實現(xiàn)這種功能的時候必須借助只能被獨享的資源。如果我們的程序是基于某個平臺的,那么就可以借助操作系統(tǒng)的內(nèi)核對象來完成,
    比如Windows操作系統(tǒng)就提供了CreateMutex這個API來創(chuàng)建一個獨享的內(nèi)核對象。但是因為要考慮平臺無關(guān),Java程序的實例控制不應(yīng)該使用系統(tǒng)的內(nèi)核對象來完成,那??
    么我們就必須找到其它的、可以獨享的資源。實際上,一臺機器無論是在什么操作系統(tǒng)上,網(wǎng)絡(luò)端口都是獨享的,也就是說基于網(wǎng)絡(luò)端口這個獨享的原理,我們可以很方
    便地讓我們的Java程序?qū)崿F(xiàn)在內(nèi)存里面只有一個運行實例這個功能,而且這個功能的實現(xiàn)是與平臺無關(guān)的。??????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???????????????????????????????????????????????????????????????????????? 實現(xiàn)????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    我們先來看看第一種情況是如何實現(xiàn)的,也就是說如果系統(tǒng)中已經(jīng)存在運行實例的話,那么結(jié)束原有的運行實例,讓新實例運行。這個實現(xiàn)實例控制的Java類也是一個線
    程,具體的實現(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(); //有連接到來,也就是說有新的實例????????????????????????????????????????????????????????????????????????????????????????????????
    ???? System.exit(0); //這個實例退出??????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????}catch (Exception e)??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????{????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???? e.printStackTrace();????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????}????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? }??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??}??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    下面這個Java程序的程序入口是沒有實例控制功能的:????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??public class ProgramMain {??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? public static void main(String argv[])????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? {??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????mainFrame frame = new mainFrame();????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? }??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??}??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    現(xiàn)在想加入實例控制,只需要添加兩行代碼,添加后代碼如下所示:????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??public class ProgramMain {??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? public static void main(String argv[])????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? {??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????InstanceControl ic = new InstanceControl();??????????????????????????????????????????????????????????????????????????????????????????????????????
    ????ic.start();??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????mainFrame frame = new mainFrame();????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? }??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??}??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    在這個基礎(chǔ)上,要實現(xiàn)第二種情況,也就是已經(jīng)有實例運行的情況下,新的實例退出,保持原有的運行實例,就只需要一點小的改動了。具體的實現(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); //連接成功,說明有實例存在,則退出??????????????????????????????????????????????????????????????????????????????????????????????
    ????}catch (Exception e)??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????{}????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????try{??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???? ServerSocket server = new ServerSocket(22222);//創(chuàng)建socket,連接22222端口????????????????????????????????????????????????????????????????????????
    ???? while (true)????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???? {????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????server.accept(); //接受連接請求????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???? }????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????}catch (Exception e)??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????{????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???? e.printStackTrace();????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ????}????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ?? }??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??}??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    這個類的使用方法和第一種情況的那個類是一樣的,只需要在原有的代碼上加入兩行代碼即可:????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??InstanceControl2 ic = new InstanceControl();????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??ic.start();????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ???????????????????????????????????????????????????????????????????????? 擴展????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
    上面的程序也許有一個小bug,就是如果程序在開始運行時ServerSocket監(jiān)聽的端口已經(jīng)被其它程序占用,那么程序的運行就會受到影響。所以程序的端口應(yīng)該盡量取得??
    大一些,在這種情況下其它程序占用這個程序使用的端口的概率是可以忽略不計的。同時,還可以做兩種擴展,第一種是把端口寫在配置文件中,可通過讀配置文件得到
    端口,這樣就能夠在其它程序占用目前端口的情況下改變這個程序使用的端口。還有一種是在運行的時候用兩個InstanceControl類分別在兩個端口監(jiān)聽,只要有一個????
    InstanceControl類得到連接就做出響應(yīng),這樣兩個端口都被其它程序占用的概率就更加的微乎其微了。??????????????????????????????????????????????????????????
    ???????????????????????????????????
    posted on 2006-12-11 11:46 蘆葦 閱讀(520) 評論(0)  編輯  收藏 所屬分類: JAVA
    主站蜘蛛池模板: 亚洲女人影院想要爱| 亚洲一级毛片免费在线观看| 伊人免费在线观看| 亚洲色av性色在线观无码| 成人免费777777| 久久久久久久久久免免费精品 | 免费欧洲毛片A级视频无风险| 国产精品内射视频免费| 亚洲在成人网在线看| 亚洲国产人成中文幕一级二级| 18级成人毛片免费观看| 男女交性无遮挡免费视频| 亚洲资源在线观看| 亚洲国产成人a精品不卡在线 | 久久亚洲国产成人影院网站| 91精品国产免费久久国语麻豆| 香蕉视频亚洲一级| 亚洲高清在线mv| 中文字幕精品亚洲无线码一区应用| 黄页网站免费观看| 成人电影在线免费观看| 朝桐光亚洲专区在线中文字幕 | 亚洲国产一成久久精品国产成人综合 | 在线综合亚洲欧洲综合网站| 亚洲婷婷五月综合狠狠爱| 日韩精品免费一区二区三区| 久久久久久国产精品免费免费男同| 国产成人亚洲综合在线| 亚洲精品国产啊女成拍色拍| 青青草原亚洲视频| 国产免费私拍一区二区三区| 嫖丰满老熟妇AAAA片免费看| 免费91最新地址永久入口| 十八禁的黄污污免费网站| 亚洲午夜福利在线视频| 亚洲色成人网一二三区| 亚洲成a人片在线观看无码| 亚洲第一黄色网址| 国产成人一区二区三区免费视频| 在线视频免费观看高清| 精品无码AV无码免费专区|