package com.netty.learning;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* 用于記錄線程池池的 狀態(tài)和當(dāng)前待work線程數(shù)量
* 前3位記錄線程池狀態(tài)
* 后29位記錄運(yùn)行work數(shù)量
*/
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
/** Java 中Integer 類型長(zhǎng)度為32位诉儒,線程池用一個(gè)int類型的前3位表示線程池的狀態(tài)**/
private static final int COUNT_BITS = Integer.SIZE - 3;
/** 用來(lái)計(jì)算出當(dāng)前線程池狀態(tài)中間變量凳忙,同時(shí)也表示work最大數(shù)量
* 00011111 11111111 11111111 11111111
**/
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
/** -----------------線程池狀態(tài)----------------- **/
/**
* 線程池RUNNING狀態(tài),當(dāng)前狀態(tài)下線程池可以接收新的任務(wù),對(duì)新接收的任務(wù)進(jìn)行處理霎挟,
* 工廠正常運(yùn)行
*
* -1 二進(jìn)制 11111111111111111111111111111111 左移動(dòng) 29位 前三位 111
*/
private static final int RUNNING = -1 << COUNT_BITS;
/**
* 線程池SHUTDOWN狀態(tài),當(dāng)前狀態(tài)下線程池不在接收新任務(wù),對(duì)之前接收的任務(wù)(其中包括還在隊(duì)列等待和正在執(zhí)行的任務(wù))
* 工廠不在接收新的訂單,工廠運(yùn)行出現(xiàn)了問(wèn)題
*
* 0 二進(jìn)制 00000000000000000000000000000000 左移動(dòng) 29位 前三位 000
*/
private static final int SHUTDOWN = 0 << COUNT_BITS;
/**
* 線程池STOP狀態(tài),當(dāng)前狀態(tài)下線程池不在接收新任務(wù)艺栈,對(duì)之前接收的任務(wù)存在隊(duì)列沒(méi)有處理的不在處理敢艰,正在執(zhí)行做中斷
* 工廠不在接收新的訂單,工廠要倒閉了
*
* 1 二進(jìn)制 00000000000000000000000000000001 左移動(dòng) 29位 前三位 001
*/
private static final int STOP = 1 << COUNT_BITS;
/**
* 線程池TIDYING狀態(tài),當(dāng)前沒(méi)有待執(zhí)行的任務(wù),等待執(zhí)行注冊(cè)到JVM的鉤子函數(shù)terminated()
* 工廠走倒閉程序诡曙,需要做最后清理工作
*
* 2 二進(jìn)制 00000000000000000000000000000010 左移動(dòng) 29位 前三位 010
*/
private static final int TIDYING = 2 << COUNT_BITS;
/**
* 執(zhí)行完VM的鉤子函數(shù)terminated()
* 工廠關(guān)閉
* 3 二進(jìn)制 00000000000000000000000000000011 左移動(dòng) 29位 前三位 011
*/
private static final int TERMINATED = 3 << COUNT_BITS;
/** 計(jì)算獲取當(dāng)前線程池狀態(tài) **/
private static int runStateOf(int c) { return c & ~CAPACITY; }
/** 計(jì)算獲取當(dāng)前運(yùn)行work數(shù)量**/
private static int workerCountOf(int c) { return c & CAPACITY; }
/**
* 即根據(jù)線程池的狀態(tài)和worker數(shù)量合并成整形 ctl
*/
private static int ctlOf(int rs, int wc) { return rs | wc; }
/** 判斷當(dāng)前線程池是否小于s,c表示當(dāng)前線程池狀態(tài) **/
private static boolean runStateLessThan(int c, int s) {
return c < s;
}
/** 判斷當(dāng)前線程池是否大于等于s,c表示當(dāng)前線程池狀態(tài) **/
private static boolean runStateAtLeast(int c, int s) {
return c >= s;
}
/** 判斷當(dāng)前線程池是否正在正常運(yùn)行 RUNNING狀態(tài)**/
private static boolean isRunning(int c) {
return c < SHUTDOWN;
}
/**
* 使用CAS增加線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算)
* 成功返回true,失敗返回false
*/
private boolean compareAndIncrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect + 1);
}
/**
* 使用CAS減少線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算)
* 成功返回true,失敗返回false
*/
private boolean compareAndDecrementWorkerCount(int expect) {
return ctl.compareAndSet(expect, expect - 1);
}
/**
* 使用CAS減少線程池中work數(shù)量(后29位可以直接整數(shù)運(yùn)算),失敗循環(huán)繼續(xù)嘗試直到成功
*/
private void decrementWorkerCount() {
do {} while (! compareAndDecrementWorkerCount(ctl.get()));
}
private final BlockingQueue<Runnable> workQueue;
/**
* 存放worker線程的集合
*/
private final HashSet<Worker> workers = new HashSet<Worker>();
/**
* 控制ThreadPoolExecutor的全局可重入鎖
*/
private final ReentrantLock mainLock = new ReentrantLock();
/**
* 控制ThreadPoolExecutor的全局可重入鎖
*/
private final Condition termination = mainLock.newCondition();
/**
* 記錄work數(shù)量(片段值)
*/
private int largestPoolSize;
/**
* 完成任務(wù)數(shù)量
*/
private long completedTaskCount;
/**
* work線程構(gòu)造工廠
*/
private volatile ThreadFactory threadFactory;
/**
* 線程池?zé)o法接收新任務(wù)時(shí),拒絕執(zhí)行任務(wù)處理器种柑,可以自定義
*/
private volatile RejectedExecutionHandler handler;
/**
* work線程(非核心線程)空閑的時(shí)間岗仑,大于此時(shí)間是被銷毀
*/
private volatile long keepAliveTime;
/**
* 是否允許回收核心work線程
*/
private volatile boolean allowCoreThreadTimeOut;
/**
* 線程池中核心work線程的數(shù)量。
*/
private volatile int corePoolSize;
/**
* 線程池中允許的最大work數(shù)量
*/
private volatile int maximumPoolSize;
private static final RejectedExecutionHandler defaultHandler =
new AbortPolicy();
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
/**
* work使用AQS同步鎖,用來(lái)判斷當(dāng)前work能否接收新任務(wù)
*
* 同步狀態(tài)0聚请,表示空閑 可以接收新任務(wù)
* 同步狀態(tài)1荠雕,表示正在執(zhí)行任務(wù) 無(wú)法接收新任務(wù)
*
* 獲取同步狀態(tài)將 同步狀態(tài)設(shè)置為1 ,釋放同步狀態(tài)設(shè)置為0
*/
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
private static final long serialVersionUID = 6138294804551838833L;
/** 工作線程*/
final Thread thread;
/** 初始化Worker驶赏,分配的第一個(gè)任務(wù) */
Runnable firstTask;
/** 每個(gè)work執(zhí)行的任務(wù)數(shù)量 */
volatile long completedTasks;
/**
* 實(shí)例化Worker
*/
Worker(Runnable firstTask) {
setState(-1);
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** 工作線程執(zhí)行炸卑,調(diào)用外部TheadPoolExecutor.runWorker方法 */
public void run() {
runWorker(this);
}
/**
* 判斷當(dāng)前Work是否空閑
*/
protected boolean isHeldExclusively() {
return getState() != 0;
}
/**
* tryAcquire 為AQS 嘗試獲取獨(dú)占同步狀態(tài)模板方法實(shí)現(xiàn)。
*/
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
/**
* tryRelease為AQS 嘗試釋放獨(dú)占同步狀態(tài)模板方法實(shí)現(xiàn)煤傍。
*/
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
/**
* 獲取獨(dú)占同步狀態(tài)
*/
public void lock() { acquire(1); }
/**
* 嘗試獲取同步狀態(tài)
*/
public boolean tryLock() { return tryAcquire(1); }
/**
* 釋放獨(dú)占同步狀態(tài)
*/
public void unlock() { release(1); }
/**
* 判斷能夠護(hù)球同步狀態(tài)
*/
public boolean isLocked() { return isHeldExclusively(); }
/**
* 中斷work正在執(zhí)行任務(wù)
*/
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
/**
* CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown
*/
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
/**
* 嘗試將線程池狀態(tài)設(shè)置為Terminate
*/
final void tryTerminate() {
for (;;) {
int c = ctl.get();
/**
* 判斷線程池能否進(jìn)入TERMINATED狀態(tài)
* 如果以下3中情況任一為true盖文,return,不進(jìn)行終止
* 1蚯姆、還在運(yùn)行狀態(tài)
* 2五续、狀態(tài)是TIDYING、或 TERMINATED龄恋,已經(jīng)終止過(guò)了
* 3疙驾、SHUTDOWN 且 workQueue不為空
* 4
*/
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
/** 線程池workQueue不為空 return,并中斷workQueue其中一個(gè)work**/
/**
* 線程池為stop狀態(tài)郭毕,且還存在work,中斷喚醒一個(gè)正在等任務(wù)的空閑worker它碎,
* 再次調(diào)用getTask(),線程池狀態(tài)發(fā)生改變,返回null,work工作線程退出循環(huán)
*/
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 將線程池狀態(tài)設(shè)置為TIDYING **/
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
/** 釋放子類實(shí)現(xiàn) **/
terminated();
} finally {
/** 將線程池狀態(tài)設(shè)置為TERMINATED **/
ctl.set(ctlOf(TERMINATED, 0));
/** 釋放鎖 **/
termination.signalAll();
}
return;
}
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
// else retry on failed CAS
}
}
/*
* Methods for controlling interrupts to worker threads.
*/
/**
* 檢查調(diào)用者是否有權(quán)限shutdown線程池
*/
private void checkShutdownAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(shutdownPerm);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
security.checkAccess(w.thread);
} finally {
mainLock.unlock();
}
}
}
/**
* Interrupts all threads, even if active. Ignores SecurityExceptions
* (in which case some threads may remain uninterrupted).
*/
private void interruptWorkers() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers)
w.interruptIfStarted();
} finally {
mainLock.unlock();
}
}
/**
* 找到斷線程池中空閑的work,中斷其工作線程
* onlyOne=true 表示僅僅中斷一個(gè)空閑的work
* onlyOne=false 表示中斷所有空閑的work
*/
private void interruptIdleWorkers(boolean onlyOne) {
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 獲取鎖 **/
mainLock.lock();
try {
/** 遍歷所有work **/
for (Worker w : workers) {
Thread t = w.thread;
/** 判斷work工作線程是否沒(méi)有被中斷扳肛,且能獲取獨(dú)占同步狀態(tài)(空閑) **/
if (!t.isInterrupted() && w.tryLock()) {
try {
/** 中斷work工作線程 **/
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
}
/**
* 找到斷線程池中空閑的work傻挂,中斷其工作線程
*/
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
private static final boolean ONLY_ONE = true;
/**
* 調(diào)用handler拒絕策略
*/
final void reject(Runnable command) {
//handler.rejectedExecution(command, this);
}
/**
* 調(diào)用shutdown時(shí)運(yùn)行狀態(tài)轉(zhuǎn)換后執(zhí)行最后一步的清理模板方法
*/
void onShutdown() {
}
/**
* 判斷線程池狀態(tài)是RUNNING或SHUTDOWN,默認(rèn)僅狀態(tài)為RUNNING返回true
* @param shutdownOK ==tue 時(shí) 狀態(tài)為SHUTDOWN也返回true
*/
final boolean isRunningOrShutdown(boolean shutdownOK) {
int rs = runStateOf(ctl.get());
return rs == RUNNING || (rs == SHUTDOWN && shutdownOK);
}
/**
* 將workQueue中的元素放入一個(gè)List并返回
*/
private List<Runnable> drainQueue() {
BlockingQueue<Runnable> q = workQueue;
ArrayList<Runnable> taskList = new ArrayList<Runnable>();
/** 將隊(duì)列中的值全部從隊(duì)列中移除,并賦值給對(duì)應(yīng)集合 **/
q.drainTo(taskList);
/** 并發(fā)在判斷 workQueue是否為空挖息,將新添加加入到taskList**/
if (!q.isEmpty()) {
for (Runnable r : q.toArray(new Runnable[0])) {
if (q.remove(r))
taskList.add(r);
}
}
return taskList;
}
/**
* 創(chuàng)建一個(gè)work執(zhí)行任務(wù)
* @param firstTask 任務(wù)(可以分配一個(gè)null,僅僅創(chuàng)建一個(gè)work)
* @param core 是否創(chuàng)建的是一個(gè)core work
* @return
*/
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
/** 無(wú)需循環(huán)校驗(yàn)金拒,成功推出 **/
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
/**
* 校驗(yàn)?zāi)芊駝?chuàng)建一個(gè)work
* rs > SHUTDOWN情況下,線程池狀態(tài)處于 旋讹,STOP殖蚕、TIDYING、TERMINATED狀態(tài)都不接收新任務(wù) 退出
*
* 當(dāng)rs == SHUTDOWN 需要 firstTask == null && 沉迹!workQueue.isEmpty() 表示創(chuàng)建一個(gè)work執(zhí)行空任務(wù)。就是去執(zhí)行任務(wù)隊(duì)列任務(wù)可以通過(guò)校驗(yàn)
* 其他情況 退出
*
* **/
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
/** 使用CASwork數(shù)量+1 **/
for (;;) {
/** 獲取當(dāng)前work數(shù)量 **/
int wc = workerCountOf(c);
/** 核心work數(shù)量大于corePoolSize害驹,總work大于maximumPoolSize直接返回 **/
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
/** worker + 1,成功跳出retry循環(huán) **/
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
/** 如果狀態(tài)不等于之前獲取的state鞭呕,跳出內(nèi)層循環(huán),繼續(xù)去外層循環(huán)判斷 **/
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
/** 創(chuàng)建work并執(zhí)行任務(wù) **/
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
/** 實(shí)例化:Worker宛官,并分配任務(wù)firstTask **/
w = new Worker(firstTask);
final Thread t = w.thread;
/** work中工作線程不為null **/
if (t != null) {
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 獲取當(dāng)前線程池狀態(tài) **/
int rs = runStateOf(ctl.get());
/** 當(dāng)前線程池狀態(tài)為運(yùn)行葫松,或當(dāng)前線程池狀態(tài)為SHUTDOWN,提交是null任務(wù)
* 將創(chuàng)建的work添加到workers集合中
* **/
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
/** 創(chuàng)建成功底洗,啟動(dòng)work執(zhí)行任務(wù) **/
if (workerAdded) {
/** 啟動(dòng)work **/
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
/** 失敗創(chuàng)建work只能當(dāng)前線程池狀態(tài)不是運(yùn)行狀態(tài) **/
addWorkerFailed(w);
}
return workerStarted;
}
/**
* 失敗創(chuàng)建work只能當(dāng)前線程池狀態(tài)不是運(yùn)行狀態(tài)
*/
private void addWorkerFailed(Worker w) {
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 嘗試從workers刪除腋么,感覺(jué)沒(méi)啥用, **/
if (w != null)
workers.remove(w);
/** 將work數(shù)量-1 **/
decrementWorkerCount();
/** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
tryTerminate();
} finally {
/** 釋放 **/
mainLock.unlock();
}
}
/**
* 執(zhí)行work銷毀退出操作
* work 要結(jié)束的worker
* completedAbruptly 表示是否需要對(duì)work數(shù)量-1操作
* runWorker 正常執(zhí)行時(shí) completedAbruptly 為false
* runWorker 執(zhí)行出現(xiàn)異常 completedAbruptly 為true
*/
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
/** 從workers 集合中移除worker **/
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
mainLock.unlock();
}
/** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
tryTerminate();
int c = ctl.get();
/** **/
if (runStateLessThan(c, STOP)) {
/** 如果 work正常退出亥揖,需要判斷當(dāng)前線程數(shù)量 < 要維護(hù)的線程數(shù)量 如果是addWorker()添加一個(gè)非核心work **/
if (!completedAbruptly) {
/**
* 如果允許回收核心線程珊擂,且workQueue還存在需要處理任務(wù) work線程需要大于1
* 如果不允許回收核心線程,則work線程需要大于corePoolSize
* **/
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
/** 如果 work 是異常退出 addWorker() 添加一個(gè)非核心work**/
addWorker(null, false);
}
}
/**
* 從WorkQueue獲取任務(wù)
* 同時(shí)用來(lái)判斷work何時(shí)退出銷毀
*/
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
/** 無(wú)限循環(huán)费变,
* 當(dāng)work超過(guò)指定時(shí)間沒(méi)有獲取時(shí)摧扇,設(shè)置timedOut = true進(jìn)行二次遍歷時(shí)銷毀當(dāng)前work **/
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
/** 線程池中狀態(tài) >= STOP 或者 線程池狀態(tài) == SHUTDOWN且阻塞隊(duì)列為空,則停止worker - 1挚歧,return null **/
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
/** 獲取work數(shù)量 **/
int wc = workerCountOf(c);
/** 判斷是否需要開(kāi)啟work淘汰機(jī)制 **/
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
/**
* 以下幾種情況直接銷毀當(dāng)前work
*
* 超時(shí)沒(méi)有獲取任務(wù)timedOut=tue,for循環(huán)遍歷第二次時(shí)
* 當(dāng)前任務(wù)超過(guò)maximumPoolSize
* **/
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
/**
* 如果開(kāi)啟work淘汰機(jī)制超時(shí)獲取任務(wù)扛稽,調(diào)用poll阻塞獲取任務(wù),存在超時(shí)滑负,如果超時(shí)沒(méi)有獲取到任務(wù)
* 設(shè)置timedOut = true 進(jìn)入第二次循環(huán)銷毀
*
* 如果沒(méi)開(kāi)啟work淘汰機(jī)制超時(shí)獲取任務(wù)在张,調(diào)用take阻塞獲取任務(wù)
* 【這里的阻塞都能被中斷響應(yīng)!矮慕!】
**/
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
/**
* work執(zhí)行邏輯帮匾。
* 內(nèi)部存在一個(gè)for循環(huán),不斷循環(huán)獲取任務(wù)執(zhí)行凡傅。當(dāng)線程池狀態(tài)還在運(yùn)行辟狈,work線程會(huì)一直運(yùn)行不會(huì)推出循環(huán)
* getTask()線程返回null時(shí)退出,一般可能當(dāng)前work超時(shí)被銷毀或線程池不在運(yùn)行。
* @param w
*/
final void runWorker(Worker w) {
/** 獲取當(dāng)前線程 **/
Thread wt = Thread.currentThread();
/** 獲取執(zhí)行任務(wù)**/
Runnable task = w.firstTask;
/** 將任務(wù)從work清理**/
w.firstTask = null;
/** 初始化同步狀態(tài)為0(創(chuàng)建時(shí)為-1) **/
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
/**
* 如果當(dāng)前work中存在任務(wù)則執(zhí)行哼转,不存在則從WorkQueue獲取任務(wù)
* getTask()明未!=null 時(shí)work永遠(yuǎn)不停止
* **/
while (task != null || (task = getTask()) != null) {
/** 獲取work獨(dú)占同步狀態(tài) **/
w.lock();
/** 如果當(dāng)前線程池的狀態(tài)為STOP,將work中工作線程標(biāo)記為中斷
* 1壹蔓、如果線程池狀態(tài)>=stop趟妥,且當(dāng)前線程沒(méi)有設(shè)置中斷狀態(tài),wt.interrupt()
2佣蓉、如果一開(kāi)始判斷線程池狀態(tài)<stop披摄,但Thread.interrupted()為true,即線程已經(jīng)被中斷勇凭,又清除了中斷標(biāo)示疚膊,再次判斷線程池狀態(tài)是否>=stop
是,再次設(shè)置中斷標(biāo)示虾标,wt.interrupt()
* 否寓盗,不做操作,清除中斷標(biāo)示后進(jìn)行后續(xù)步驟
*
* **/
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
/** 模板方法給子類擴(kuò)展 **/
beforeExecute(wt, task);
Throwable thrown = null;
try {
/** 處理任務(wù) **/
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
/** 模板方法給子類擴(kuò)展 **/
afterExecute(task, thrown);
}
} finally {
/** 重置任務(wù) **/
task = null;
/** work執(zhí)行的任務(wù)數(shù)量 **/
w.completedTasks++;
/** 釋放work獨(dú)占同步狀態(tài) **/
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
/**
* 創(chuàng)建一個(gè)線程池,使用默認(rèn)線程池的拒絕策略和創(chuàng)建work工廠
* @param corePoolSize 線程池中核心work線程的數(shù)量璧函。
* @param maximumPoolSize 線程池中允許的最大work數(shù)量
* @param keepAliveTime work線程(非核心線程)空閑的時(shí)間傀蚌,大于此時(shí)間是被銷毀
* @param unit keepAliveTime的單位。TimeUnit
* @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
/**
* 創(chuàng)建一個(gè)線程池,使用默認(rèn)線程池的拒絕策略
* @param corePoolSize 線程池中核心work線程的數(shù)量蘸吓。
* @param maximumPoolSize 線程池中允許的最大work數(shù)量
* @param keepAliveTime work線程(非核心線程)空閑的時(shí)間善炫,大于此時(shí)間是被銷毀
* @param unit keepAliveTime的單位。TimeUnit
* @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
* @param threadFactory 創(chuàng)建work工廠
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
/**
* 創(chuàng)建一個(gè)線程池,使用默認(rèn)的創(chuàng)建work工廠
* @param corePoolSize 線程池中核心work線程的數(shù)量库继。
* @param maximumPoolSize 線程池中允許的最大work數(shù)量
* @param keepAliveTime work線程(非核心線程)空閑的時(shí)間箩艺,大于此時(shí)間是被銷毀
* @param unit keepAliveTime的單位。TimeUnit
* @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
* @param handler 線程池的拒絕策略
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
/**
* 創(chuàng)建一個(gè)線程池制跟,
* @param corePoolSize 線程池中核心work線程的數(shù)量舅桩。
* @param maximumPoolSize 線程池中允許的最大work數(shù)量
* @param keepAliveTime work線程(非核心線程)空閑的時(shí)間,大于此時(shí)間是被銷毀
* @param unit keepAliveTime的單位雨膨。TimeUnit
* @param workQueue 用來(lái)保存等待執(zhí)行的任務(wù)的阻塞隊(duì)列
* @param threadFactory 創(chuàng)建work工廠
* @param handler 線程池的拒絕策略
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
/**
* 執(zhí)行任務(wù)
*/
public void execute(Runnable command) {
/** 提交任務(wù)為null 拋出異常擂涛。 **/
if (command == null)
throw new NullPointerException();
/** 獲取ctl **/
int c = ctl.get();
/** work線程數(shù)量少于corePoolSize **/
if (workerCountOf(c) < corePoolSize) {
/** 創(chuàng)建新work線程并設(shè)置為核心線程執(zhí)行任務(wù) addWorker(command, true) **/
if (addWorker(command, true))
return;
c = ctl.get();
}
/** 進(jìn)入此邏輯表示work線程數(shù)量大于corePoolSize或者前一步執(zhí)行失敗 **/
/** 判斷線程池是Running運(yùn)行狀態(tài),將任務(wù)添加到workQueue尾部成功(隊(duì)列滿了返回false) **/
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
/** Double Check下當(dāng)前線程狀態(tài)是不是Running運(yùn)行狀態(tài)聊记,不是就刪除剛剛添加的任務(wù)撒妈,執(zhí)行拒絕任務(wù) **/
if (! isRunning(recheck) && remove(command))
reject(command);
/** 異常情況 前面workerCountOf(c) < corePoolSize說(shuō)明當(dāng)時(shí)還存在大量work,說(shuō)明線程池突然停止排监,為保證任務(wù)都能處理狰右,
* 創(chuàng)建一個(gè)臨時(shí)work去處理當(dāng)前workQueue中的任務(wù) **/
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
/** 隊(duì)列滿了,創(chuàng)建一個(gè)非核心work執(zhí)行新添加任務(wù) **/
else if (!addWorker(command, false))
/** 執(zhí)行失敗舆床,執(zhí)行拒絕任務(wù) **/
reject(command);
}
/**
* 溫柔的終止線程池
*/
public void shutdown() {
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 判斷調(diào)用者是否有權(quán)限shutdown線程池 **/
checkShutdownAccess();
/** CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown **/
advanceRunState(SHUTDOWN);
/** 找到斷線程池中空閑的work棋蚌,中斷其工作線程 **/
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
/** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
tryTerminate();
}
/**
* 強(qiáng)硬的終止線程池
* 返回在隊(duì)列中沒(méi)有執(zhí)行的任務(wù)
*/
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
/** 判斷調(diào)用者是否有權(quán)限shutdown線程池 **/
checkShutdownAccess();
/** CAS+循環(huán)設(shè)置線程池狀態(tài)為shutdown **/
advanceRunState(STOP);
/** 找到斷線程池中空閑的work嫁佳,中斷其工作線程 **/
interruptWorkers();
tasks = drainQueue();
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
/** 嘗試將線程池狀態(tài)設(shè)置為Terminate **/
tryTerminate();
return tasks;
}
/**
* 判斷當(dāng)前線程池狀態(tài)是非運(yùn)行狀態(tài)
*/
public boolean isShutdown() {
return ! isRunning(ctl.get());
}
/**
* 判斷線程池正在停止到TERMINATED狀態(tài)過(guò)程中
*/
public boolean isTerminating() {
int c = ctl.get();
return ! isRunning(c) && runStateLessThan(c, TERMINATED);
}
/**
* 返回線程池 狀態(tài)是否為TERMINATED
*/
public boolean isTerminated() {
return runStateAtLeast(ctl.get(), TERMINATED);
}
/**
* 等待線程終止
* @param timeout
* @param unit
* @return
* @throws InterruptedException
*/
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
/** 獲取等待時(shí)間 **/
long nanos = unit.toNanos(timeout);
/** 獲取主鎖:mainLock **/
final ReentrantLock mainLock = this.mainLock;
/** 加鎖 **/
mainLock.lock();
try {
for (;;) {
/** 當(dāng)線程狀態(tài)為終止時(shí)返回 **/
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
/** 超時(shí)返回 **/
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
/** 釋放鎖 **/
mainLock.unlock();
}
}
protected void finalize() {
shutdown();
}
/**
* 設(shè)置 threadFactory
*/
public void setThreadFactory(ThreadFactory threadFactory) {
if (threadFactory == null)
throw new NullPointerException();
this.threadFactory = threadFactory;
}
/**
* 獲取 threadFactory
*/
public ThreadFactory getThreadFactory() {
return threadFactory;
}
/**
* 設(shè)置 handler
*/
public void setRejectedExecutionHandler(RejectedExecutionHandler handler) {
if (handler == null)
throw new NullPointerException();
this.handler = handler;
}
/**
* 獲取 handler
*/
public RejectedExecutionHandler getRejectedExecutionHandler() {
return handler;
}
/**
* 設(shè)置corePoolSize
*/
public void setCorePoolSize(int corePoolSize) {
if (corePoolSize < 0)
throw new IllegalArgumentException();
int delta = corePoolSize - this.corePoolSize;
this.corePoolSize = corePoolSize;
if (workerCountOf(ctl.get()) > corePoolSize)
interruptIdleWorkers();
else if (delta > 0) {
// We don't really know how many new threads are "needed".
// As a heuristic, prestart enough new workers (up to new
// core size) to handle the current number of tasks in
// queue, but stop if queue becomes empty while doing so.
int k = Math.min(delta, workQueue.size());
while (k-- > 0 && addWorker(null, true)) {
if (workQueue.isEmpty())
break;
}
}
}
/**
* 返回corePoolSize
*/
public int getCorePoolSize() {
return corePoolSize;
}
/**
* 如果線程池中work線程數(shù)量小于corePoolSize,添加一個(gè)核心work
*/
public boolean prestartCoreThread() {
return workerCountOf(ctl.get()) < corePoolSize &&
addWorker(null, true);
}
/**
* 添加一個(gè)work
*/
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0)
addWorker(null, false);
}
/**
* 初始化添加核心work到corePoolSize
*/
public int prestartAllCoreThreads() {
int n = 0;
while (addWorker(null, true))
++n;
return n;
}
/**
* 返回 allowCoreThreadTimeOut
*/
public boolean allowsCoreThreadTimeOut() {
return allowCoreThreadTimeOut;
}
/**
* 設(shè)置 allowCoreThreadTimeOut 設(shè)置為true
* 找到斷線程池中空閑的work谷暮,中斷其工作線程
* @since 1.6
*/
public void allowCoreThreadTimeOut(boolean value) {
if (value && keepAliveTime <= 0)
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
if (value != allowCoreThreadTimeOut) {
allowCoreThreadTimeOut = value;
if (value)
interruptIdleWorkers();
}
}
/**
* 設(shè)置maximumPoolSize蒿往,如果設(shè)置maximumPoolSize大于原始值
* 找到斷線程池中空閑的work,中斷其工作線程
*/
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}
/**
* 返回maximumPoolSize
*/
public int getMaximumPoolSize() {
return maximumPoolSize;
}
/**
* 設(shè)置keepAliveTime湿弦,如果keepAliveTime小于原始值
* 找到斷線程池中空閑的work瓤漏,中斷其工作線程
*/
public void setKeepAliveTime(long time, TimeUnit unit) {
if (time < 0)
throw new IllegalArgumentException();
if (time == 0 && allowsCoreThreadTimeOut())
throw new IllegalArgumentException("Core threads must have nonzero keep alive times");
long keepAliveTime = unit.toNanos(time);
long delta = keepAliveTime - this.keepAliveTime;
this.keepAliveTime = keepAliveTime;
if (delta < 0)
interruptIdleWorkers();
}
/**
* 返回 keepAliveTime
*/
public long getKeepAliveTime(TimeUnit unit) {
return unit.convert(keepAliveTime, TimeUnit.NANOSECONDS);
}
/* User-level queue utilities */
/**
* 返回workQueue
*/
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
/**
* 從workQueue 刪除task
*/
public boolean remove(Runnable task) {
boolean removed = workQueue.remove(task);
tryTerminate(); // In case SHUTDOWN and now empty
return removed;
}
/**
* 遍歷線程池所有work,將工作線程狀態(tài)為取消的刪除
*/
public void purge() {
final BlockingQueue<Runnable> q = workQueue;
try {
Iterator<Runnable> it = q.iterator();
while (it.hasNext()) {
Runnable r = it.next();
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
it.remove();
}
} catch (ConcurrentModificationException fallThrough) {
for (Object r : q.toArray())
if (r instanceof Future<?> && ((Future<?>)r).isCancelled())
q.remove(r);
}
tryTerminate();
}
/* Statistics */
/**
* 獲取work數(shù)量
*/
public int getPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return runStateAtLeast(ctl.get(), TIDYING) ? 0
: workers.size();
} finally {
mainLock.unlock();
}
}
/**
* 獲取正在執(zhí)行任務(wù)work
*/
public int getActiveCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
int n = 0;
for (Worker w : workers)
if (w.isLocked())
++n;
return n;
} finally {
mainLock.unlock();
}
}
/**
* 獲取work數(shù)量
*/
public int getLargestPoolSize() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
return largestPoolSize;
} finally {
mainLock.unlock();
}
}
/**
* 獲取待完成任務(wù)
*/
public long getTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers) {
n += w.completedTasks;
if (w.isLocked())
++n;
}
return n + workQueue.size();
} finally {
mainLock.unlock();
}
}
/**
* 獲取線程池完成任務(wù)總理
*/
public long getCompletedTaskCount() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
long n = completedTaskCount;
for (Worker w : workers)
n += w.completedTasks;
return n;
} finally {
mainLock.unlock();
}
}
/**
* 線程池用字符串及表示
*/
public String toString() {
long ncompleted;
int nworkers, nactive;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
ncompleted = completedTaskCount;
nactive = 0;
nworkers = workers.size();
for (Worker w : workers) {
ncompleted += w.completedTasks;
if (w.isLocked())
++nactive;
}
} finally {
mainLock.unlock();
}
int c = ctl.get();
String rs = (runStateLessThan(c, SHUTDOWN) ? "Running" :
(runStateAtLeast(c, TERMINATED) ? "Terminated" :
"Shutting down"));
return super.toString() +
"[" + rs +
", pool size = " + nworkers +
", active threads = " + nactive +
", queued tasks = " + workQueue.size() +
", completed tasks = " + ncompleted +
"]";
}
/* Extension hooks */
/**
* 模板方法給子類實(shí)現(xiàn)颊埃,執(zhí)行任務(wù)前的操作
*/
protected void beforeExecute(Thread t, Runnable r) { }
/**
* 模板方法給子類實(shí)現(xiàn)蔬充,執(zhí)行任務(wù)后的操作
*/
protected void afterExecute(Runnable r, Throwable t) { }
/**
* 模板方法給子類實(shí)現(xiàn),線程池狀態(tài)從TIDYING到TERMINATED需要做的清理動(dòng)作
*/
protected void terminated() { }
/* Predefined RejectedExecutionHandlers */
/**
* A handler for rejected tasks that runs the rejected task
* directly in the calling thread of the {@code execute} method,
* unless the executor has been shut down, in which case the task
* is discarded.
*/
public static class CallerRunsPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code CallerRunsPolicy}.
*/
public CallerRunsPolicy() { }
/**
* Executes task r in the caller's thread, unless the executor
* has been shut down, in which case the task is discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
}
/**
* A handler for rejected tasks that throws a
* {@code RejectedExecutionException}.
*/
public static class AbortPolicy implements RejectedExecutionHandler {
/**
* Creates an {@code AbortPolicy}.
*/
public AbortPolicy() { }
/**
* Always throws RejectedExecutionException.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
* @throws RejectedExecutionException always
*/
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +
" rejected from " +
e.toString());
}
}
/**
* A handler for rejected tasks that silently discards the
* rejected task.
*/
public static class DiscardPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardPolicy}.
*/
public DiscardPolicy() { }
/**
* Does nothing, which has the effect of discarding task r.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
}
}
/**
* A handler for rejected tasks that discards the oldest unhandled
* request and then retries {@code execute}, unless the executor
* is shut down, in which case the task is discarded.
*/
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
/**
* Creates a {@code DiscardOldestPolicy} for the given executor.
*/
public DiscardOldestPolicy() { }
/**
* Obtains and ignores the next task that the executor
* would otherwise execute, if one is immediately available,
* and then retries execution of task r, unless the executor
* is shut down, in which case task r is instead discarded.
*
* @param r the runnable task requested to be executed
* @param e the executor attempting to execute this task
*/
public void rejectedExecution(Runnable r, java.util.concurrent.ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
}
}
J.U.C之線程池07:源碼解析-完整解釋
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門纽谒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人如输,你說(shuō)我怎么就攤上這事鼓黔。” “怎么了不见?”我有些...
- 文/不壞的土叔 我叫張陵澳化,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我稳吮,道長(zhǎng)缎谷,這世上最難降的妖魔是什么? 我笑而不...
- 正文 為了忘掉前任灶似,我火速辦了婚禮列林,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘酪惭。我一直安慰自己希痴,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布春感。 她就那樣靜靜地躺著砌创,像睡著了一般虏缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嫩实,一...
- 那天刽辙,我揣著相機(jī)與錄音,去河邊找鬼舶赔。 笑死扫倡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的竟纳。 我是一名探鬼主播撵溃,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼锥累!你這毒婦竟也來(lái)了缘挑?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤桶略,失蹤者是張志新(化名)和其女友劉穎语淘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體际歼,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡惶翻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹅心。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吕粗。...
- 正文 年R本政府宣布议泵,位于F島的核電站,受9級(jí)特大地震影響桃熄,放射性物質(zhì)發(fā)生泄漏先口。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一蜻拨、第九天 我趴在偏房一處隱蔽的房頂上張望池充。 院中可真熱鬧,春花似錦缎讼、人聲如沸收夸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卧惜。三九已至厘灼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咽瓷,已是汗流浹背设凹。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像钻洒,于是被迫代替她去往敵國(guó)和親奋姿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 創(chuàng)建線程屬性 我們可以通過(guò)ThreadPoolExecutor構(gòu)造函數(shù)來(lái)創(chuàng)建一個(gè)線程池: 線程池的創(chuàng)建
- 線程池終止 線程池ThreadPoolExecutor提供了shutdown()和shutDownNow()用于關(guān)...
- 前言 本文會(huì)分析到ThreadPoolExecutor的線程池是如何工作的,包括基本屬性,內(nèi)部類Worker,核心...
- 親愛(ài)的牛圈伙伴們素标,大家好称诗,我是牛牛。今天想先給大家講個(gè)事情头遭,一件發(fā)生在我身上寓免,讓我特別氣憤的事~五一小長(zhǎng)假第...