Java通過Executors提供四種線程池,分別為:
newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
注意:線程池只是為了控制應用中處理某項業務中防止高並發問題帶來的線程不安全的發生的概率。在我目前的測試用,還沒有發現線程可以重用這個概念,因為線程開啟后,用完就關閉了,不可以再次開啟的,查看源碼發現會每次新創建一個線程用來處理業務。我們可以通過線程池指定處理這項業務最大的同步線程數,比如:Executors.newFixedThreadPool(3);在線程池中保持三個線程可以同時執行,但是注意,並不是說線程池中永遠都是這三個線程,只是說可以同時存在的線程數,當某個線程執行結束后,會有新的線程進來。newFixedThreadPool.execute(new ThreadForpools());這句話的含義並不是添加新的線程,而是添加新的處理業務請求進來。至少我當前是這么理解的,沒有發現線程可以重復使用。
處理線程代碼:
package com.alivn.sockets; /** * Created by Alivn on 2017/3/19. */ public class ThreadForpools implements Runnable{ private Integer index; public ThreadForpools(Integer index) { this.index=index; } @Override public void run() { /*** * 業務......省略 */ try { System.out.println("開始處理線程!!!"); Thread.sleep(index*100); System.out.println("我的線程標識是:"+this.toString()); } catch (InterruptedException e) { e.printStackTrace(); } } }
(1) newCachedThreadPool
創建一個可緩存線程池,應用中存在的線程數可以無限大
示例代碼如下:
package com.alivn.sockets; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by Alivn on 2017/3/19. */ public class Threadpools { /** * 我們獲取四次次線程,觀察4個線程地址 * @param args */ public static void main(String[]args) { ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); System.out.println("****************************newCachedThreadPool*******************************"); for(int i=0;i<4;i++) { final int index=i; newCachedThreadPool.execute(new ThreadForpools(index)); } } }
輸出結果是:可以有無限大的線程數進來(線程地址不一樣)
(2) newFixedThreadPool
創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。示例代碼如下:
package com.alivn.sockets; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by Alivn on 2017/3/19. */ public class Threadpools { /** * 我們獲取四次次線程,觀察4個線程地址 * @param args */ public static void main(String[]args) { //線程池允許同時存在兩個線程 ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(2); System.out.println("****************************newFixedThreadPool*******************************"); for(int i=0;i<4;i++) { final int index=i; newFixedThreadPool.execute(new ThreadForpools(index)); } } }
輸出結果:每次只有兩個線程在處理,當第一個線程執行完畢后,新的線程進來開始處理(線程地址不一樣)
(3) newScheduledThreadPool
創建一個定長線程池,支持定時及周期性任務執行。延遲執行示例代碼如下:
package com.alivn.sockets; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by Alivn on 2017/3/19. */ public class Threadpools { /** * 我們獲取四次次線程,觀察4個線程地址 * @param args */ public static void main(String[]args) { ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(2); System.out.println("****************************newFixedThreadPool*******************************"); for(int i=0;i<4;i++) { final int index=i; //延遲三秒執行 newScheduledThreadPool.schedule(new ThreadForpools(index),3, TimeUnit.SECONDS); } } }
執行結果:延遲三秒之后執行,除了延遲執行之外和newFixedThreadPool基本相同,可以用來執行定時任務
4) newSingleThreadExecutor
創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。示例代碼如下:
package com.alivn.sockets; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * Created by Alivn on 2017/3/19. */ public class Threadpools { /** * 我們獲取四次次線程,觀察4個線程地址 * @param args */ public static void main(String[]args) { ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); System.out.println("****************************newFixedThreadPool*******************************"); for(int i=0;i<4;i++) { final int index=i; newSingleThreadExecutor.execute(new ThreadForpools(index)); } } }
執行結果:只存在一個線程,順序執行