線程池
1.1、什麼是線程池?
線程池是指在初始化一個多線程應用程序過程中創建一個線程集合,然後在需要執行新的任務時重用這些線程而不是新建一個線程。線程池中線程的數量通常完全取決於可用內存數量和應用程序的需求。然而,增加可用線程數量是可能的。線程池中的每個線程都有被分配一個任務,一旦任務已經完成了,線程回到池子中並等待下一次分配任務。
1.2、線程池作用
基於以下幾個原因在多線程應用程序中使用線程是必須的:
1. 線程池改進了一個應用程序的響應時間。由於線程池中的線程已經準備好且等待被分配任務,應用程序可以直接拿來使用而不用新建一個線程。
2. 線程池節省了CLR 爲每個短生存週期任務創建一個完整的線程的開銷並可以在任務完成後回收資源。
3. 線程池根據當前在系統中運行的進程來優化線程時間片。
4. 線程池允許我們開啓多個任務而不用爲每個線程設置屬性。
5. 線程池允許我們爲正在執行的任務的程序參數傳遞一個包含狀態信息的對象引用。
6. 線程池可以用來解決處理一個特定請求最大線程數量限制問題。
1.3 、 線程池四種創建方式
Java通過Executors(jdk1.5併發包)提供四種線程池,分別爲:
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。
newFixedThreadPool 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。
newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
① newCachedThreadPool
創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。示例代碼如下:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int index = i; // try { // Thread.sleep(index * 1000); // } catch (InterruptedException e) { // e.printStackTrace(); // } cachedThreadPool.execute(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName() + "---" + index); } }); } |
總結: 線程池爲無限大,當執行第二個任務時第一個任務已經完成,會複用執行第一個任務的線程,而不用每次新建線程。
② newFixedThreadPool
創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。示例代碼如下:
// 創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待 final ExecutorService newCachedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) { final int index = i; newCachedThreadPool.execute(new Runnable() { public void run() { try { Thread.sleep(1000); } catch (Exception e) { // TODO: handle exception } System.out.println("i:" + index); } }); } |
總結:因爲線程池大小爲3,每個任務輸出index後sleep 2秒,所以每兩秒打印3個數字。
定長線程池的大小最好根據系統資源進行設置。如Runtime.getRuntime().availableProcessors()
③ newScheduledThreadPool
創建一個定長線程池,支持定時及週期性任務執行。延遲執行示例代碼如下:
// 創建一個定長線程池,支持定時及週期性任務執行。延遲執行示例代碼如下: ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5); newScheduledThreadPool.schedule(new Runnable() { public void run() { System.out.println("delay 3 seconds"); } }, 3, TimeUnit.SECONDS); |
表示延遲3秒執行。
④ newSingleThreadExecutor
創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。示例代碼如下:
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); for (int i = 0; i < 10; i++) { final int index = i; newSingleThreadExecutor.execute(new Runnable() {
@Override public void run() { System.out.println("index:" + index); try { Thread.sleep(200); } catch (Exception e) { // TODO: handle exception } } }); } |