java ->多線程_線程池

來源:互聯網
上載者:User

標籤:遊泳池   return   sum   except   over   image   封裝   service   string   

線程池概念

線程池,其實就是一個容納多個線程的容器,其中的線程可以反覆使用,省去了頻繁建立線程對象的操作,無需反覆建立線程而消耗過多資源。

 

 

我們詳細的解釋一下為什麼要使用線程池?(程式最佳化)

在java中,如果每個請求到達就建立一個新線程,開銷是相當大的。在實際使用中,建立和銷毀線程花費的時間和消耗的系統資源都相當大,甚至可能要比在處理實際的使用者請求的時間和資源要多的多。除了建立和銷毀線程的開銷之外,活動的線程也需要消耗系統資源。如果在一個jvm裡建立太多的線程,可能會使系統由於過度消耗記憶體或“切換過度”而導致系統資源不足。為了防止資源不足,需要採取一些辦法來限制任何給定時刻處理的請求數目,儘可能減少建立和銷毀線程的次數,特別是一些資源耗費比較大的線程的建立和銷毀,盡量利用已有對象來進行服務。

線程池主要用來解決線程生命週期開銷問題和資源不足問題。通過對多個任務重複使用線程,線程建立的開銷就被分攤到了多個任務上了,而且由於在請求到達時線程已經存在,所以消除了線程建立所帶來的延遲。這樣,就可以立即為請求服務,使用應用程式響應更快。另外,通過適當的調整線程中的線程數目可以防止出現資源不足的情況。

 

使用線程池方式--Runnable介面

通常,線程池都是通過線程池工廠建立,再調用線程池中的方法擷取線程,再通過線程去執行任務方法。                                                                                                                      

l  Executors:線程池建立工廠類

n  public static ExecutorService newFixedThreadPool(int nThreads):返回線程池對象

l  ExecutorService:線程池類

n  Future<?> submit(Runnable task):擷取線程池中的某一個線程對象,並執行

l  Future介面:用來記錄線程任務執行完畢後產生的結果。線程池建立與使用

 

l  使用線程池中線程對象的步驟:

n  建立線程池對象

n  建立Runnable介面子類對象(建立任務)

n  提交Runnable介面子類對象(執行任務)

n  關閉線程池

代碼示範:

public class ThreadPoolDemo {

    public static void main(String[] args) {

        //建立線程池對象

        ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象

        //建立Runnable執行個體對象

        MyRunnable r = new MyRunnable();

       

        //自己建立線程對象的方式

        //Thread t = new Thread(r);

        //t.start(); ---> 調用MyRunnable中的run()

       

        //從線程池中擷取線程對象,然後調用MyRunnable中的run()

        service.submit(r);

        //再擷取個線程對象,調用MyRunnable中的run()

        service.submit(r);

        service.submit(r);

//注意:submit方法調用結束後,程式並不終止,是因為線程池控制了線程的關閉。將使用完的線程又歸還到了線程池中

 

//關閉線程池

        //service.shutdown();

    }

}

l  Runnable介面實作類別

public class MyRunnable implements Runnable {

    @Override

    public void run() {

        System.out.println("我要一個教練");

       

        try {

            Thread.sleep(2000);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        System.out.println("教練來了: " +Thread.currentThread().getName());

        System.out.println("教我遊泳,交完後,教練回到了遊泳池");

    }

}

 

使用線程池方式—Callable介面(專用於線程池)

l  Callable介面:與Runnable介面功能相似,用來指定線程的任務。其中的call()方法,用來返回線程任務執行完畢後的結果,call方法可拋出異常可設定傳回值。

l  ExecutorService:線程池類

n  <T> Future<T> submit(Callable<T> task):擷取線程池中的某一個線程對象,並執行線程中的call()方法

l  Future介面:用來記錄線程任務執行完畢後產生的結果。線程池建立與使用

 

l  使用線程池中線程對象的步驟:

n  建立線程池對象

n  建立Callable介面子類對象

n  提交Callable介面子類對象

n  關閉線程池

代碼示範:

public class ThreadPoolDemo {

    public static void main(String[] args) {

        //建立線程池對象

        ExecutorService service = Executors.newFixedThreadPool(2);//包含2個線程對象

        //建立Callable對象

        MyCallable c = new MyCallable();

       

        //從線程池中擷取線程對象,然後調用MyRunnable中的run()

        service.submit(c);

       

        //再擷取個教練

        service.submit(c);

        service.submit(c);

//注意:submit方法調用結束後,程式並不終止,是因為線程池控制了線程的關閉。將使用完的線程又歸還到了線程池中

 

//關閉線程池

        //service.shutdown();

    }

}

l  Callable介面實作類別,call方法可拋出異常、返回線程任務執行完畢後的結果

public class MyCallable implements Callable {

    @Override

    public Object call() throws Exception {

        System.out.println("我要一個教練:call");

        Thread.sleep(2000);

        System.out.println("教練來了: " +Thread.currentThread().getName());

        System.out.println("教我遊泳,交完後,教練回到了遊泳池");

        return null;

    }

}

 

線程池練習:返回兩個數相加的結果

要求:通過線程池中的線程對象,使用Callable介面完成兩個數求和操作

l  Future介面:用來記錄線程任務執行完畢後產生的結果。

n  V get() 擷取Future對象中封裝的資料結果

代碼示範:

public class ThreadPoolDemo {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        //建立線程池對象

        ExecutorService threadPool = Executors.newFixedThreadPool(2);

       

        //建立一個Callable介面子類對象

        //MyCallable c = new MyCallable();

        MyCallable c = new MyCallable(100, 200);

        MyCallable c2 = new MyCallable(10, 20);

       

        //擷取線程池中的線程,調用Callable介面子類對象中的call()方法, 完成求和操作

        //<Integer> Future<Integer> submit(Callable<Integer> task)

        // Future 結果對象

        Future<Integer> result = threadPool.submit(c);

        //此 Future 的 get 方法所返回的結果類型

        Integer sum = result.get();

        System.out.println("sum=" + sum);

       

        //再示範

        result = threadPool.submit(c2);

        sum = result.get();

        System.out.println("sum=" + sum);

 

    }

}

l  Callable介面實作類別

public class MyCallable implements Callable<Integer> {

    //成員變數

    int x = 5;

    int y = 3;

    //構造方法

    public MyCallable(){

    }

    public MyCallable(int x, int y){

        this.x = x;

        this.y = y;

    }

 

    @Override

    public Integer call() throws Exception {

        return x+y;

    }

}

java ->多線程_線程池

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.