先解釋一下兩個概念,核心線程數和最大線程數的差別,比如電商網站平常我們可以用50個線程來處理使用者的所有請求,但是當雙十一的時候請求明顯增多這是我們需要用500個線程來解決使用者的請求,50就是核心線程數,500就是最大線程數
先上線程池流程圖吧

第一種Executors.newCacheThreadPool()
這種方式沒有入參,核心線程數為0個,最大線程數為Integer.maxValue空閑線程60m關閉,使用簡單無需參數
第二種Executors.newFixedThreaPool(設定核心線程數及最大線程數)
這種方式可以根據我們伺服器的配置來動态設定最大線程數提高硬體使用率
第三種Executors.newSingleThreadPool()
顧名思義就是隻有一個線程來處理任務
第四種Executors.newScheduledThreadPool(設定核心線程數)
這種方式可以做定時功能,傳回值為ScheduledExecutorService,設傳回值為m可以使用m.schedule(Runnable,定時時長,時長機關)方法來定時執行Runnable中的任務,也可以調用m.scheduleAtFixedRate(Runnable,定時時長,執行頻率,時長機關)方法來延時執行Runnable中的任務并每過一段時間(執行頻率)重複執行。這個也有Single的類這裡就不說了
第五種ForkJoin.commonPool()獲得一個ForkJoinPool類
這種線程池展現的是一種分治思想需要任務類繼承RecursiveAction這個抽象類把一個任務分解成多個子任務來執行
常見的線程池我能想到的就上述五種,而對于上述五種都不建議采用,原因是入參太少了,不利于我們控制線程池的參數,靈活性差,翻閱源碼他們最終都是new的ThreadPoolExecutor類,下面我們分析一下ThreadPoolExecutor類
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
上面是建立線程池的方法以及參數
**corePoolSize代表線程池的核心線程數
maximumPoolSize代表線程池的最大線程數
keepAliveTime表示空閑線程多久關閉
unit表示關閉時間的機關
workQueue表示當核心線程滿時的阻塞隊列
ThreadFactory 表示線程工廠一般使用預設的
handler表示丢棄政策**
以比較複雜一點的延遲線程池為例
ExecutorService m = new ThreadPoolExecutor(
1 //代表線程池的核心線程數
,10 //代表線程池的最大線程數
,60L //表示空閑線程多久關閉
,TimeUnit.SECONDS //表示關閉時間的機關
,new DelayQueue()//表示當核心線程滿時的阻塞隊列
,new ThreadPoolExecutor.DiscardPolicy()
//表示丢棄政策
);
前四個參數沒有什麼好說的從阻塞隊列開始,阻塞隊列常用的有四種:
**LinkedBlockingQueue 基于連結清單的生産消費使用兩把鎖可以同時進行
ArrayBlockingQueue 基于數組是以需要提前制定大小,且生産消費使用同一把鎖不可以同時進行
DelayedWorkQueue 可以對任務進行定時,生産消費使用同一把鎖。
SynchornoursQueue 與上述阻塞隊列不同,同步阻塞隊列不存儲任務,隻負責将生産線程的資料搬運給消費線程,吞吐量高。**
對于定時的線程池我們需要我們添加的任務類必須實作了Delayed接口并且是一個線程類,上代碼
private long timeOut;
private long delayTime;
//初始化時需要設定到期時間以納秒為機關
public DelayedTask(long timeOut){
this.timeOut = timeOut;
this.delayTime = System.nanoTime()+TimeUnit.NANOSECONDS.convert(timeOut,TimeUnit.SECONDS);
}
//傳回還有多長時間任務需要被執行
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(this.delayTime-System.nanoTime(),TimeUnit.NANOSECONDS);
}
@Override
public int compareTo(Delayed o) {
if(o == this){
return 0;
}
if(o.getDelay(TimeUnit.NANOSECONDS)<this.getDelay(TimeUnit.NANOSECONDS)){
return 1;
}
return -1;
}
上述代碼為延時阻塞隊列中任務的要求
可以像ScheduledExecutorService一樣直接添加任務就行到時自動會執行
下一個參數丢棄政策
ThreadPoolExecutor類中定義了四種丢棄政策,當核心線程、阻塞隊列已滿且目前線程數已經達到最大值時線程池就會執行丢棄政策。
AbortPolicy:丢棄該任務并抛出異常
DiscardPolicy:丢棄任務但不抛出異常
DiscardOldestPolicy:丢棄最舊的未處理的任務然後重試
CallerRunsPolicy:使用送出任務的線程來執行任務
關于線程池的阻塞隊列用什麼還是需要根據業務需求來定,本文章僅為參考