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

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

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

    和風細雨

    世上本無難事,心以為難,斯乃真難。茍不存一難之見于心,則運用之術自出。

    線程的創建

    單線程程序

    一般來說,在沒有線程的幫助下,程序在一個時間段只能執行一段代碼,其它代碼段只有在等待它完成后才能執行。該程序的處理流程從頭到尾只有一條線,這樣的程序我們稱之為單線程程序(Single Thread Program)

    典型的單線程程序:
    public class SingleThreadProgram{
      public static void main(String[] args){
        for(int i=0;i<1000;i++){
          System.out.print("SingleThreadProgram");
        }
      }
    }

    多線程程序

    當程序由一個以上的線程所構成時,稱此程序為多線程程序(Multithread Program),java從設計伊始就把程序的多線程能力列入了考慮范圍。
    典型的多線程程序有:

    1)GUI應用程序,我們目前做的Swing桌面程序就屬于此類。
    2)較花費時間的I/O處理,一般來說,文件和網絡的輸入/輸出處理比較花費時間,如果在這段無法進行其它處理,則程序性能會大打折扣,遇到這種情況首先要想到用多線程解決問題.
    3)多連接網絡處理。

    并發(Concurrent)與并行(Parallel)

    當有多個線程在操作時,如果系統只有一個CPU,則它根本不可能真正同時進行一個以上的線程,它只能把CPU運行時間劃分成若干個時間段,再將時間段分配給各個線程執行,在一個時間段的線程代碼運行時,其它線程處于掛起狀態.這種方式我們稱之為并發(Concurrent).
    當系統有一個以上CPU時,則線程的操作有可能非并發.當一個CPU執行一個線程時,另一個CPU可以執行另一個線程,兩個線程互不搶占CPU資源,可以同時進行,這種方式我們稱之為并行(Parallel)



    多線程在并發和并行環境中的不同作用

    在并發環境時,多線程不可能真正充分利用CPU,節約運行時間,它只是以”掛起->執行->掛起”的方式以很小的時間片分別運行各個線程,給用戶以每個線程都在運行的錯覺.在這種環境中,多線程程序真正改善的是系統的響應性能和程序的友好性.
    在并行環境中, 一個時刻允許多個線程運行,這時多線程程序才真正充分利用了多CPU的處理能力, 節省了整體的運行時間.在這種環境中,多線程程序能體現出它的四大優勢:充分利用CPU,節省時間,改善響應和增加程序的友好性.

    PS:在多核時代來臨后,開發多線程程序的能力更是每個程序員都該具備的.

    創建多線程程序

    創建多線程程序我們通常有兩種方法:
    1)讓類繼承java.lang.Thread,這種方法優勢在于調用稍微方便,一般用于后臺批處理程序的場合,但劣勢是類無法再繼承別的類。
    2)讓類實現接口java.lang.Runnable,這種方法調用時需要借助Thread的幫助,稍顯麻煩,但優勢在于對類繼承體系沒有影響,這是使用線程時最常用的方法。
    兩種方法的線程執行部分都在run()函數中,它們的效率沒有差別。

    多線程程序創建和啟動示例

    創建線程

    // 繼承Thread類
    public class Thread1 extends Thread{
      public void run(){
        while(true){
          System.out.println("<Thread1 extends Thread>");
        }
      }
    }

    // 實現Runnable接口
    public class Thread2 implements Runnable{
      public void run(){
        while(true){
          System.out.println("<Thread2 implements Runnable>");
        }
      }
    }

    啟動線程

    public class Main{
      public static void main(String[] args){
        // 啟動線程1,Thread1直接繼承自java.lang.Thread類
        Thread1 th1=new Thread1();
        th1.start();
       
        // 啟動線程2,thread2實現自java.lang.Runnable接口
        Thread2 thread2=new Thread2();
        Thread th2=new Thread(thread2);
        th2.start();
       
        while(true){
          System.out.println("<Main Thread>");
        }
      }
    }

    概念解析Start和Run

    public void run()
    這個函數容納線程啟動后執行的代碼塊,線程啟動起來,run函數中的代碼會得到執行.

    Thead.start()
    這是啟動一個線程的方法,調用了這個方法后,線程才會得到執行.

    取得線程執行的結果

    通過觀察run函數的簽名public void run()我們可以發現,它既沒有輸入參數,也沒有返回值,那如何取得線程的返回值呢?一般來說我們有三種辦法:
    1)讓線程修改公有變量,如某類的靜態公有字段.這種方式古老而危險,最好不要采用.
    2)輪詢線程執行結果,線程執行的結果放在線程類的一個字段中,外界不斷通過輪詢去查看執行結果.這種方式會浪費很多時間,結果也不可靠,不建議采用.
    3)回調方式,把調用方的指針通過線程類的構造函數傳入線程類的一個字段中,當線程執行完取得結果后再通過這個字段反向調用調用方的函數.這是取得線程執行結果的最佳解決方案.

    下面請看回調方式的實現.

    Boss類
    這個類用于啟動Secretary線程去查找文件, findFile()是啟動線程并查找的函數, giveBossResult(String file,String reult)是供Secretary類回調的函數.

    public class Boss{
      private String name;
     
      public Boss(String name){
        this.name=name;
      }
     
      public void giveBossResult(String file,String reult){
        if(reult!=null){
          System.out.println("文件"+file+"序列號等于:"+reult);
        }
        else{
          System.out.println("無法找到文件"+file);
        }
      }
     
      public void findFile(){  
        Map<String,String> files=new Hashtable<String,String>();   
        files.put("001", "員工花名冊");
        files.put("002", "企業收支");
        files.put("003", "客戶花名錄");
        files.put("004", "對手狀況分析");
        files.put("005", "當月收支");
        files.put("006", "市場份額分析");
        files.put("007", "大連酒店一覽");
        files.put("008", "娛樂場所名錄");
        files.put("009", "關系單位聯系名錄");
       
        Secretary andy=new Secretary("Andy",this,"員工花名冊",files);
        Thread th1=new Thread(andy);
        th1.start();
       
        Secretary cindy=new Secretary("cindy",this,"上市情況分析",files);
        Thread th2=new Thread(cindy);
        th2.start();
      }
     
      public static void main(String[] args){
        Boss boss=new Boss("Bill");
        boss.findFile();
      }
    }

    Secretary類

    這個類是進行多線程查找文件的類,查找的結果通過回調方法告知Boss實例.
    Boss實例,查找的文件名,查找的集合都通過Secretary類的構造函數傳進來.

    public class Secretary implements Runnable{
      private String name;
      private Boss boss;
      private String file;
      private Map<String,String> files;
     
      public Secretary(String name,Boss boss,String file,Map<String,String> files){
        this.name=name;
        this.boss=boss;
        this.file=file;
        this.files=files;
      }
     
      public void run(){
        for(Map.Entry<String,String> entry:files.entrySet()){
             if(entry.getValue().equals(file)){
               boss.giveBossResult(file,entry.getKey());
               return;
             }
        }
       
        boss.giveBossResult(file,null);
      }
    }

    posted on 2008-02-22 12:34 和風細雨 閱讀(1968) 評論(1)  編輯  收藏 所屬分類: 線程

    評論

    # re: 線程的創建 2008-08-02 16:55 天堂明月

    回調方式返回數據是個不錯的方法
      回復  更多評論   

    主站蜘蛛池模板: 亚洲欧洲日产国码在线观看| 免费v片在线观看无遮挡| 亚洲成a人片在线观看无码专区| 免费无码国产V片在线观看| 免费一级特黄特色大片在线观看| 亚洲熟女www一区二区三区| 成年女人午夜毛片免费视频| 亚洲人成人无码.www石榴| 天堂在线免费观看中文版| 亚洲爆乳成av人在线视菜奈实| 国产成人精品男人免费| 美美女高清毛片视频黄的一免费 | 亚洲乱码无人区卡1卡2卡3| 免费高清小黄站在线观看| 亚洲av无码成人精品国产| 日韩亚洲国产二区| 91视频精品全国免费观看| 亚洲视频在线视频| 国产在线a免费观看| 亚洲AV无码一区二区三区牲色| 亚洲Av无码乱码在线znlu| 久久久久久久久久久免费精品| 亚洲va无码手机在线电影| 成人免费的性色视频| 亚洲国产精品无码中文lv| 亚洲AV无码成人精品区大在线| 在线播放免费人成毛片乱码| 亚洲欧洲精品在线| 国产成人免费永久播放视频平台| 黄色视屏在线免费播放| 久久久亚洲AV波多野结衣| 男人的好看免费观看在线视频| 在线亚洲v日韩v| 亚洲AV日韩AV永久无码久久 | 免费91麻豆精品国产自产在线观看| 亚洲av无码一区二区三区不卡 | 一级一黄在线观看视频免费| 日韩亚洲AV无码一区二区不卡| 永久免费视频v片www| 中文无码成人免费视频在线观看| 波多野结衣亚洲一级|