CONAN ZONE

          你越掙扎我就越興奮

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
          在有些方法里, 比如登陸,一般需要順序調(diào)用多個(gè)系統(tǒng)功能才能完成初始化操作.
          比如 安全校驗(yàn)-》獲取用戶權(quán)限-》獲取用戶設(shè)置信息-》獲取系統(tǒng)字典 等等, 在某些EAI模式的應(yīng)用里,這些調(diào)用可能都是遠(yuǎn)程調(diào)用,每個(gè)調(diào)用時(shí)間可能從0.5秒到數(shù)秒不等, 這樣累計(jì)下來用戶一個(gè)登陸操作,在后臺(tái)處理時(shí)間可能就有3,4秒,加上網(wǎng)絡(luò)傳輸延時(shí),會(huì)主觀上給用戶造成系統(tǒng)很慢的感覺。

          在單個(gè)方法調(diào)用效率無法改進(jìn)的前提下,一個(gè)簡(jiǎn)單的辦法是將調(diào)用方式由串行改為并行,即以多個(gè)thread分別去完成方法調(diào)用,最后匯總。

          在java 5以前,因?yàn)榫€程的特性限制,必須手工編碼實(shí)現(xiàn)線程完成狀態(tài)的調(diào)用檢查。

          比如
           // thread 
          public void run() {
              ......
             finished = true;
           }
            
            public boolean isFinished() {
             return finished;
            }


          // 以阻塞循環(huán)的方式檢查是否執(zhí)行完畢
          while(!remoteCall.isFinished()) {
              try {
                  Thread.sleep(100);
             } catch (InterruptedException e) {
               e.printStackTrace();
              }
          }

          這樣的代碼是繁瑣,較低效率,也容易出錯(cuò)的,尤其在線程多于2個(gè)的時(shí)候。而在服務(wù)器方代碼中過多的線程使用又可能會(huì)導(dǎo)致內(nèi)存溢出和資源泄露。

          今天翻書的時(shí)候發(fā)現(xiàn)java 5中的cucurrent包對(duì)此進(jìn)行了改進(jìn) 繼承自Callable 的類有能力將執(zhí)行結(jié)果返回,并且可以自行檢查執(zhí)行是否結(jié)束。

            public class RandomPrimeSearch implements Callable<BigInteger> {
                 public BigInteger call( ) {
                      // do operation here
                      return BigInteger.probablePrime(bitSize, prng);
                 }
            }

            FutureTask<BigInteger> task =     new FutureTask<BigInteger>(new RandomPrimeSearch(512));  //需要利用泛型模板返回處理結(jié)果
            new Thread(task).start( );

            BigInteger result = task.get( );  //此處會(huì)自動(dòng)判斷是否執(zhí)行結(jié)束,未結(jié)束會(huì)繼續(xù)等待。也可以設(shè)定最大等待時(shí)間
              
              //為了提高效率 也可以使用service方式調(diào)用
              ExecutorService service = Executors.newFixedThreadPool(5);

              Future<BigInteger> prime1 = service.submit(new RandomPrimeSearch(512));


          這樣一來,使用這種并發(fā)模式處理代碼就容易多了。程序可以簡(jiǎn)單的修改為這樣的結(jié)構(gòu)
          remoateCall1 = doRemoteCall1();  // 啟動(dòng)線程1 將方法處理以封裝到線程中
          remoateCall2 = doRemoteCall2();  // 啟動(dòng)線程2

          remoteCall1.get().getUserSetting() ;
          remoteCall2.get().getDictionaryList(); 
          ....

          呵呵,基本和順序執(zhí)行時(shí)差不多,代碼修改量比較小。

          java 5中引入了線程執(zhí)行服務(wù)ExecutorService 的概念以后, 如果以線程池的方式執(zhí)行線程調(diào)用,資源消耗會(huì)大幅度減少,所以不用太擔(dān)心并發(fā)處理會(huì)產(chǎn)生過多的系統(tǒng)負(fù)荷。

          posted on 2008-07-08 23:02 CONAN 閱讀(259) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 乌拉特前旗| 曲阜市| 马公市| 广灵县| 徐州市| 攀枝花市| 峨边| 祁连县| 永济市| 东辽县| 延吉市| 盘锦市| 衡阳市| 临夏县| 巫溪县| 孟津县| 保德县| 和田市| 兖州市| 高平市| 仲巴县| 杭州市| 贵德县| 建湖县| 论坛| 长兴县| 马关县| 桓台县| 治多县| 富裕县| 全南县| 锦屏县| 新巴尔虎左旗| 罗定市| 麻栗坡县| 柏乡县| 德化县| 桐柏县| 秭归县| 密山市| 古交市|