【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )
文章目錄
- 前言
- 一、ThreadPoolExecutor 構造參數
- 二、newCachedThreadPool 參數分析
- 三、newFixedThreadPool 參數分析
- 四、newSingleThreadExecutor 參數分析
前言
在上一篇博客 【Java 并發編程】線程池機制 ( 線程池示例 | newCachedThreadPool | newFixedThreadPool | newSingleThreadExecutor ) 使用了 333 種類型的線程池 , 333 種線程池都使用了 ThreadPoolExecutor , 該類時線程池的核心 ;
本篇博客中分析這 333 種線程池 ;
一、ThreadPoolExecutor 構造參數
ThreadPoolExecutor 是線程池中最核心的類 , 其構造函數如下 :
public ThreadPoolExecutor(int corePoolSize, // 核心線程數 , 這些線程基本不會被銷毀int maximumPoolSize, // 最大線程數 , 線程池能創建的最大線程數量long keepAliveTime, // 空閑情況下 , 非核心線程存活時間TimeUnit unit, // 空閑時間單位BlockingQueue<Runnable> workQueue,// 任務的阻塞隊列ThreadFactory threadFactory, // 創建線程的工廠類RejectedExecutionHandler handler) // 拒絕策略int corePoolSize 核心線程數 , 這些線程基本不會被銷毀 ;
int maximumPoolSize 最大線程數 , 線程池能創建的最大線程數量 , 包括 核心線程 + 非核心線程 ;
long keepAliveTime 空閑情況下 , 非核心線程存活時間 ;
TimeUnit unit 空閑時間單位 ;
BlockingQueue<Runnable> workQueue 任務的阻塞隊列 , 任務設置到線程池后 , 在該隊列中排隊等待執行 ;
ThreadFactory threadFactory 創建線程的工廠類 ;
RejectedExecutionHandler handler 拒絕策略 , 如果線程池已滿 , 如果再放入新的任務后的拒絕策略
二、newCachedThreadPool 參數分析
ExecutorService executorService1 = Executors.newCachedThreadPool(); 創建線程池代碼如下 :
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}分析上述代碼中 ThreadPoolExecutor 構造函數參數 :
核心線程數 000 , 沒有核心線程 ;
最大線程數 Integer.MAX_VALUE , 值為 231?12^{31} - 1231?1 , 這些線程都是非核心線程 , 是無限大的 ; 注意這里有 OOM 風險 ;
線程的存活時間 606060 秒 ;
使用的等待隊列是 SynchronousQueue<Runnable> 隊列 ;
SynchronousQueue 隊列不存儲元素 , 后一個 Runnable 任務入隊 , 必須等到前一個任務執行完畢才可以 , 否則會一直阻塞等待 ;
使用該線程池 , 如果執行 100000100000100000 個 Runnable 任務 , 則會創建 100000100000100000 個線程 , 與 【Java 并發編程】線程池機制 ( 測試線程開銷 | 啟動線程分析 | 用戶態 | 內核態 | 用戶線程 | 內核線程 | 輕量級進程 ) 一、測試線程開銷 1、正常測試 章節測試 ;
- 首次創建 100000100000100000 線程 , 性能基本相同 , 只是添加了一個線程存活時間 ;
- 如果再次創建 100000100000100000 線程 , 此時線程池中的線程如果執行完畢 , 可以復用之前創建的 100000100000100000 線程池 , 不用重新創建線程 ; 前提是期間沒有間斷 , 如果線程間斷超過了 " 非工作線程存活時間 " , 這些線程就會被銷毀 ;
三、newFixedThreadPool 參數分析
ExecutorService executorService2 = Executors.newFixedThreadPool(10); 創建線程池代碼如下 :
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}分析上述代碼中 ThreadPoolExecutor 構造函數參數 :
核心線程數是 nThreads , 這是傳入的參數 ;
最大線程數 nThreads , 核心線程數是 nThreads , 所有的線程都是核心線程 ;
非核心線程的存活時間 000 毫秒 ; 由于所有線程都是核心線程 , 設置非核心線程存貨事件意義不大 ;
使用的等待隊列是 LinkedBlockingQueue<Runnable> 隊列 ;
LinkedBlockingQueue 隊列是基于鏈表的阻塞隊列 , 該隊列吞吐量高于 ArrayBlockingQueue 隊列 , 低于 SynchronousQueue 隊列 ;
假設核心線程數為 101010 , 有 100100100 個任務需要執行 ;
執行 100100100 個 Runnable 任務 , 如果 101010 個核心線程沒有滿 , 則將任務提交給核心線程執行 ; 如果核心線程都滿了 , 則將 Runnable 任務放到 LinkedBlockingQueue<Runnable> 等待隊列 , 假如該等待隊列中任務也滿了 , 則需要執行 RejectedExecutionHandler handler 拒絕策略 ;
該拒絕策略默認是 defaultHandler ;
private static final RejectedExecutionHandler defaultHandler =new AbortPolicy();四、newSingleThreadExecutor 參數分析
ExecutorService executorService3 = Executors.newSingleThreadExecutor(); 創建線程池代碼如下 :
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}分析上述代碼中 ThreadPoolExecutor 構造函數參數 :
核心線程數是 111 , 只有 111 個核心線程 ;
最大線程數 111 , 核心線程數是 111 , 所有的線程都是核心線程 ;
非核心線程的存活時間 000 毫秒 ; 由于所有線程都是核心線程 , 設置非核心線程存貨事件意義不大 ;
使用的等待隊列是 LinkedBlockingQueue<Runnable> 隊列 ;
LinkedBlockingQueue 隊列是基于鏈表的阻塞隊列 , 該隊列吞吐量高于 ArrayBlockingQueue 隊列 , 低于 SynchronousQueue 隊列 ;
整個線程池只有 111 個核心線程在工作 ; 100100100 個任務在 LinkedBlockingQueue<Runnable> 任務隊列中排隊等待執行 ;
總結
以上是生活随笔為你收集整理的【Java 并发编程】线程池机制 ( ThreadPoolExecutor 线程池构造参数分析 | 核心线程数 | 最大线程数 | 非核心线程存活时间 | 任务阻塞队列 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 并发编程】线程池机制 ( 线
- 下一篇: 【Java 并发编程】线程池机制 ( 线