在平常開發過程當中老是以單線程的思惟去編碼,沒有考慮到在多線程狀態下的運行情況。由此引起的結果就是請求過多,應用沒法響應。爲了解決請求過多的問題,又衍生出了線程池的概念。經過「池」的思想,從而合理的處理請求。本文記錄了Java中線程池的使用及工做原理,若有錯誤,歡迎指正。html
線程池是一種用於實現計算機程序併發執行的軟件設計模式。線程池維護多個線程,等待由調度程序分配任務以併發執行,該模型提升了性能,並避免了因爲爲短時間任務頻繁建立和銷燬線程而致使的執行延遲。
說到線程池就必定要從線程的生命週期講起。java
](/img/bVcSinY)git
從圖中能夠了解不管任務執行多久,每一個線程都要經歷從生到死的狀態。而使用線程池就是爲了不線程的重複建立,從而節省了線程的New
至Runnable
, Running
至Terminated
的時間;同時也會複用線程,最小化的節省系統資源,於此同時提升了響應速度。github
使用ThreadPoolExecutor
並配置7個參數完成線程池的建立web
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
底層基於數組的實現的有界阻塞隊列面試
底層基於單鏈表的阻塞隊列,可配置容量,不配置容量默認爲Integer.MAX_VALUE
設計模式
在《阿里巴巴Java開發手冊》中強制要求指定線程的名稱
](/img/bVcSinX)數組
因爲工做是使用hutool比較多,裏面也包含對ThreadFactory
的封裝,能夠很方便的指定名稱多線程
ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build();
當線程池內工做線程數大於maximumPoolSize時,線程就再也不接受任務,執行對應的拒絕策略;目前支持的拒絕策略有四種:併發
RejectedExecutionException
異常// 建立線程工廠 ThreadFactory threadFactory = ThreadFactoryBuilder.create().setNamePrefix("myThread-").build(); // 建立線程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), threadFactory, new ThreadPoolExecutor.AbortPolicy());
// 組合值;保存了線程池的工做狀態和工做線程數 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
public void execute(Runnable command) { // 任務爲空 拋出NPE if (command == null) throw new NullPointerException(); // 獲取線程池狀態 int c = ctl.get(); // 若是工做線程數小於核心線程數就建立新線程 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } // 若是線程池處於Running狀態,就把任務放在隊列尾部 if (isRunning(c) && workQueue.offer(command)) { // 從新檢查線程池狀態 int recheck = ctl.get(); // 若是線程池不是Running狀態,就移除剛纔添加的任務,並執行拒絕策略 if (! isRunning(recheck) && remove(command)) reject(command); // 是Running狀態,就添加線程 else if (workerCountOf(recheck) == 0) addWorker(null, false); } // 添加任務失敗,執行拒絕策略 else if (!addWorker(command, false)) reject(command); } // addWorker()完成線程的建立
參考文章: