空間站

          北極心空

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

          Swing禁止重復啟動

          許多程序只允許啟動單個實例,比如我們常用的MSN、OUTLOOK等等。單實例有很多好處,其中最重要一點即是安全。想像一下多人同時修改同一文件的危險,就如我們在J2EE應用程序中所做的那樣,要盡可能考慮到多用戶同時訪問的問題。

            前些日子用SWING為朋友寫了一個程序,其中就有不可同時啟動多個系統實例的要求。由于沒有一個好的思路,所以走了很多彎路。現在終于解決了,積累了一些心德想與大家分享。

            初遇該問題時,我首先想到的是進程。當程序啟動時判斷操作系統中是否存在該進程,如果存在就退出啟動,否則啟動程序。這個方法在VB或C語言中可以通過調用WIN32?API來實現。在JAVA中,要想實現該方法或許還要借助C的力量。(對于JAVA如何捕獲進程,還請批評指正。)

            放棄了第一種方法,想到了弱智的方法--配置文件。當系統第一次啟動時將標識設置為啟動中,退出時將標識設置為未啟動。但很快就發現,當非法關閉程序(比如關機時未及時關閉程序)后,我們的程序便永遠長眠了。

            其實,在該程序中,最限制我們思路的便是"單機版"這三個字。它給我們的印象是僅供一臺機器單獨使用,與網絡無關的。因此,我們很難將思路整理到服務器與客戶機中去。但要解決該問題恰恰要用到服務器與客戶機的概念。想像一下我們平時啟動電腦的步驟,首先按下加電,有了電,電腦才能啟動。沒錯,只有當電腦未加電,也就是說當我們首次啟動電腦時才會做這個動作,而且這個動作在一段時間內只會做一次。若要重新加電,就必需先斷電。現在回到我們的程序,有了這個思路,留給我們的問題就是誰來充當電的角色呢?沒錯,就是之前提到過的服務器。程序首次啟動時首先連接指定端口的服務器,發現服務器并未啟動,于是啟動服務器,啟動程序。當程序復數啟動時,再次連接服務器,這時發現服務器已經啟動了,于是就終止啟動。代碼如下:?

          public?class?Console?{
          ??
          /**端口號*/
          ??
          private?static?int?iPort?=?50000;
          ??
          /**主窗口*/
          ??JFrame?frame?
          =?null;?
          ??
          /**
          ??*?系統入口
          ??*?
          @param?String[]?args
          ??*?
          */
          ??
          public?static?void?main(String[]?args)?throws?Exception?{
          ????Socket?socket?
          =?null;?//客戶端連接器
          ????Thread?thread?=?null;?//啟動服務器的線程

          ????
          try?{
          ??????
          //連接服務器
          ??????
          //如果服務器未啟動則拋異常
          ??????(socket?=?new?Socket("localhost",?iPort)).close();
          ??????
          //如果服務器已經啟動則退出系統
          ??????System.exit(0);
          ????}?
          catch?(Exception?e)?{}//未做處理

          ????
          //如果服務器未啟動則在新的線程中啟動服務器
          ????(thread?=?new?Thread(new?Server())).setDaemon(true);
          ????
          //開始線程
          ????thread.start();

          ????
          //啟動主程序
          ????frame?=?new?JFrame("學海無涯");
          ????frame.setVisible(
          true);
          ??}

          ??
          /**
          ??*?端口監聽服務器端運行
          ??*?
          @author?hiswing
          ??
          */
          ??
          static?class?Server?implements?Runnable?{
          ????
          public?final?void?run()?{
          ??????ServerSocket?serversocket?
          =?null;

          ??????
          //查找沒有占用的端口
          ??????while?(iPort?<?60000)?{
          ????????
          try{
          ??????????serversocket?
          =?new?ServerSocket(iPort);
          ????????}
          catch(Exception?ex){
          ??????????iPort
          ++;
          ????????}
          ????????
          break;
          ??????}
          ??????
          try?{
          ????????
          do?{
          ??????????
          //監聽客戶端是否有連接
          ??????????serversocket.accept();

          ??????????
          //窗口在任務欄閃動
          ??????????if(frame.getExtendedState()?==?1)?{
          ????????????frame.setExtendedState(
          0);
          ??????????}
          ??????????
          if(frame.getExtendedState()?!=?1)?{
          ????????????frame.toFront();
          ????????????frame.requestFocus();
          ????????????frame.repaint();
          ??????????}
          ????????}?
          while(true);
          ??????}?
          catch?(Exception?ex)?{
          ????????
          //不做處理
          ??????}
          ????}
          ??}
          }
          由于沒有好的思路,使我們在編程中走了許多彎路,浪費了寶貴的時間。都說軟件是智慧的結晶,一點沒錯。

          posted on 2006-12-11 11:40 蘆葦 閱讀(1897) 評論(1)  編輯  收藏 所屬分類: JAVA

          Feedback

          # re: Swing禁止重復啟動 2015-03-17 12:36 dipoo
          厲害,原來可以這樣  回復  更多評論
            

          主站蜘蛛池模板: 泸水县| 沐川县| 通化市| 江安县| 静海县| 文成县| 康保县| 沈丘县| 清原| 莆田市| 江川县| 肃宁县| 红安县| 山东| 明水县| 兴宁市| 子洲县| 白沙| 陈巴尔虎旗| 读书| 乾安县| 淄博市| 郑州市| 青州市| 青岛市| 涿鹿县| 双柏县| 威信县| 上饶县| 迁西县| 岚皋县| 休宁县| 嘉善县| 潼南县| 厦门市| 普宁市| 客服| 惠安县| 吴川市| 秀山| 扎兰屯市|