1、newCachedThreadPool()
創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程
/**
* 1.創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程,那麼就會回收部分空閒(60秒不執行任務)的線程
* 2.當任務數增加時,此線程池又可以智能的添加新線程來處理任務
* 3.此線程池不會對線程池大小做限制,線程池大小完全依賴於操作系統(或者說JVM)能夠創建的最大線程大小
*/
public static void cacheThreadPool() {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 1; i <= 10; i++) {
final int ii = i;
try {
Thread.sleep(ii * 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(() -> out.println("線程名稱:" + Thread.currentThread().getName() + ",執行" + ii));
}
}
運行結果:
線程名稱:pool-1-thread-1,執行1
線程名稱:pool-1-thread-1,執行2
線程名稱:pool-1-thread-1,執行3
線程名稱:pool-1-thread-1,執行4
線程名稱:pool-1-thread-1,執行5
線程名稱:pool-1-thread-1,執行6
線程名稱:pool-1-thread-1,執行7
線程名稱:pool-1-thread-1,執行8
線程名稱:pool-1-thread-1,執行9
線程名稱:pool-1-thread-1,執行10
說明:
在Executors.java中的調用
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
在ThreadPoolExecutor.java中的調用
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
- 底層:返回ThreadPoolExecutor實例,
- corePoolSize爲0;
- maximumPoolSize爲Integer.MAX_VALUE;
- keepAliveTime爲60L;
- unit爲TimeUnit.SECONDS;
- workQueue爲SynchronousQueue(同步隊列)
- 通俗:當有新任務到來,則插入到SynchronousQueue中,由於SynchronousQueue是同步隊列,因此會在池中尋找可用線程來執行,若有可以線程則執行,若沒有可用線程則創建一個線程來執行該任務;若池中線程空閒時間超過指定大小,則該線程會被銷燬。
- 適用:執行很多短期異步的小程序或者負載較輕的服務器
2、newFixedThreadPool
創建一個定長線程池,可控制線程最大併發數,超出的線程會在隊列中等待。
/**
* 1.創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小
* 2.線程池的大小一旦達到最大值就會保持不變,如果某個線程因爲執行異常而結束,那麼線程池會補充一個新線程
* 3.因爲線程池大小爲3,每個任務輸出index後sleep 2秒,所以每兩秒打印3個數字,和線程名稱
*/
public static void fixTheadPoolTest() {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
final int ii = i;
fixedThreadPool.execute(() -> {
out.println("線程名稱:" + Thread.currentThread().getName() + ",執行" + ii);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
執行結果:
線程名稱:pool-1-thread-1,執行0
線程名稱:pool-1-thread-2,執行1
線程名稱:pool-1-thread-3,執行2
線程名稱:pool-1-thread-2,執行3
線程名稱:pool-1-thread-1,執行4
線程名稱:pool-1-thread-3,執行5
線程名稱:pool-1-thread-3,執行6
線程名稱:pool-1-thread-2,執行7
線程名稱:pool-1-thread-1,執行8
線程名稱:pool-1-thread-1,執行9
說明:
在Executors.java中的調用:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
在ThreadPoolExecutor.java中的調用
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
- 底層:返回ThreadPoolExecutor實例,
- 接收參數爲所設定線程數量nThread,
- corePoolSize爲nThread,
- maximumPoolSize爲nThread;
- keepAliveTime爲0L(不限時);
- unit爲:TimeUnit.MILLISECONDS;
- WorkQueue爲:new LinkedBlockingQueue<Runnable>() 無界阻塞隊列
- 通俗:創建可容納固定數量線程的池子,每隔線程的存活時間是無限的,當池子滿了就不在添加線程了;如果池中的所有線程均在繁忙狀態,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
- 適用:執行長期的任務,性能好很多
3、newSingleThreadExecutor
創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行
/**
* 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行
*/
public static void singleTheadPoolTest() {
ExecutorService pool = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int ii = i;
pool.execute(() -> out.println(Thread.currentThread().getName() + "=>" + ii));
}
}
運行結果:
pool-1-thread-1=>0
pool-1-thread-1=>1
pool-1-thread-1=>2
pool-1-thread-1=>3
pool-1-thread-1=>4
pool-1-thread-1=>5
pool-1-thread-1=>6
pool-1-thread-1=>7
pool-1-thread-1=>8
pool-1-thread-1=>9
說明:
在Executors.java中的調用:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
在ThreadPoolExecutor.java中的調用
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
- 底層:FinalizableDelegatedExecutorService包裝的ThreadPoolExecutor實例,
- corePoolSize爲1;
- maximumPoolSize爲1;
- keepAliveTime爲0L;
- unit爲:TimeUnit.MILLISECONDS;
- workQueue爲:new LinkedBlockingQueue<Runnable>() 無解阻塞隊列
- 通俗:創建只有一個線程的線程池,且線程的存活時間是無限的;當該線程正繁忙時,對於新任務會進入阻塞隊列中(無界的阻塞隊列)
- 適用:一個任務一個任務執行的場景
4、newScheduledThreadPool
創建一個可定期或者延時執行任務的定長線程池,支持定時及週期性任務執行。
/**
* 創建一個定長線程池,支持定時及週期性任務執行。延遲執行
*/
public static void sceduleThreadPool() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
Runnable r1 = () -> out.println("線程名稱:" + Thread.currentThread().getName() + ",執行:3秒後執行");
scheduledThreadPool.schedule(r1, 3, TimeUnit.SECONDS);
Runnable r2 = () -> out.println("線程名稱:" + Thread.currentThread().getName() + ",執行:延遲2秒後每3秒執行一次");
scheduledThreadPool.scheduleAtFixedRate(r2, 2, 3, TimeUnit.SECONDS);
Runnable r3 = () -> out.println("線程名稱:" + Thread.currentThread().getName() + ",執行:普通任務");
for (int i = 0; i < 5; i++) {
scheduledThreadPool.execute(r3);
}
}
說明:
在Executors.java中的調用:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
在ThreadPoolExecutor.java中的調用
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
- 底層:創建ScheduledThreadPoolExecutor實例,
- corePoolSize爲傳遞來的參數,
- maximumPoolSize爲Integer.MAX_VALUE;
- keepAliveTime爲0;
- unit爲:TimeUnit.NANOSECONDS;
- workQueue爲:new DelayedWorkQueue() 一個按超時時間升序排序的隊列
- 通俗:創建一個固定大小的線程池,線程池內線程存活時間無限制,線程池可以支持定時及週期性任務執行,如果所有線程均處於繁忙狀態,對於新任務會進入DelayedWorkQueue隊列中,這是一種按照超時時間排序的隊列結構
- 適用:週期性執行任務的場景