Java并發(fā)編程:線程池的使用
線程池基礎(chǔ)
- 請求隊列 線程池維護(hù)一定數(shù)量的線程胞枕,當(dāng)線程池在運行狀態(tài)的線程數(shù)量達(dá)上限時歌粥,其他線程被放入各請求隊列婚瓜,排除等待線程池釋放提供資源歼跟。
1. 線程池狀態(tài)
volatile int runState; //運行狀態(tài)
//當(dāng)創(chuàng)建線程池后,初始時声登,線程池處于RUNNING狀態(tài)
static final int RUNNING = 0;
//調(diào)用了shutdown()方法狠鸳;此時等待池內(nèi)和隊列中所有線程執(zhí)行完畢,不接受新任務(wù)
static final int SHUTDOWN = 1;
//調(diào)用了shutdownNow()方法; 此時嘗試終止正在執(zhí)行的任務(wù)悯嗓,且拒絕接受新任務(wù)
static final int STOP = 2;
//shutdown或stop 且所有工作線程銷毀件舵,隊列清空。
static final int TERMINATED = 3;
2. 任務(wù)的執(zhí)行
private final BlockingQueue<Runnable> workQueue; //任務(wù)緩存隊列脯厨,用來存放等待執(zhí)行的任務(wù)
private final ReentrantLock mainLock = new ReentrantLock(); //線程池的主要狀態(tài)鎖铅祸,對線程池狀態(tài)(比如線程池大小、runState等)的改變都要使用這個鎖
private final HashSet<Worker> workers = new HashSet<Worker>(); //用來存放工作集
private volatile long keepAliveTime; //線程存活時間
private volatile boolean allowCoreThreadTimeOut; //是否允許為核心線程設(shè)置存活時間
private volatile int corePoolSize; //核心池的大泻衔洹(即線程池中的線程數(shù)目大于這個參數(shù)時临梗,提交的任務(wù)會被放進(jìn)任務(wù)緩存隊列)
private volatile int maximumPoolSize; //線程池最大能容忍的線程數(shù)
private volatile int poolSize; //線程池中當(dāng)前的線程數(shù)
private volatile RejectedExecutionHandler handler; //任務(wù)拒絕策略
private volatile ThreadFactory threadFactory; //線程工廠,用來創(chuàng)建線程
private int largestPoolSize; //用來記錄線程池中曾經(jīng)出現(xiàn)過的最大線程數(shù)
private long completedTaskCount; //用來記錄已經(jīng)執(zhí)行完畢的任務(wù)個數(shù)
3. 線程池中的線程初始化
prestartCoreThread():初始化一個核心線程稼跳;
prestartAllCoreThreads():初始化所有核心線程
4. 任務(wù)緩存隊列及排隊策略
//任務(wù)緩存隊列盟庞,用來存放等待執(zhí)行的任務(wù)
private final BlockingQueue<Runnable> workQueue;
【排隊策略】:
- ArrayBlockingQueue : 基于數(shù)組的先進(jìn)先出阻塞隊列,必須指定數(shù)組大小
- LinkedBlckingQueue: 基于鏈表 汤善,默認(rèn)大小為Integer.MaxValue
- synchronousQueue: 這個比較特殊什猖,不會保存任務(wù)票彪,直接創(chuàng)建線程執(zhí)行任務(wù)。
5. 任務(wù)拒絕策略
【任務(wù)拒絕的前提】: 當(dāng)線程池的任務(wù)緩存隊列已滿并且線程池中的線程數(shù)目達(dá)到maximumPoolSize
【任務(wù)拒絕策略】:
- ThreadPoolExecutor.AbortPolicy //丟棄任務(wù)并拋出RejectedExecutionException異常不狮。
- DiscardPolicy //丟棄任務(wù)降铸,但不拋出異常
- DiscardOldestPolicy //丟棄隊列最前的任務(wù),嘗試重新執(zhí)行任務(wù)
- CallerRunsPolicy //由調(diào)用線程執(zhí)行該任務(wù)
6. 線程池的關(guān)閉
- shutdown():不會立即終止線程池摇零,而是要等所有任務(wù)緩存隊列中的任務(wù)都執(zhí)行完后才終止推掸,但再也不會接受新的任務(wù)
- shutdownNow():立即終止線程池,并嘗試打斷正在執(zhí)行的任務(wù)遂黍,并且清空任務(wù)緩存隊列终佛,返回尚未執(zhí)行的任務(wù)
7. 線程池容量的動態(tài)調(diào)整
ThreadPoolExecutor提供了動態(tài)調(diào)整線程池容量大小的方法:setCorePoolSize()和setMaximumPoolSize(),
- setCorePoolSize:設(shè)置核心池大小
- setMaximumPoolSize:設(shè)置線程池最大能創(chuàng)建的線程數(shù)目大小
線程池最佳數(shù)量計算
實戰(zhàn)
線程池 | 配置及持久化異常日志