Java執行緒池之ThreadPoolExecutor原始碼分析
一、引言
Java併發工具包自帶了很多常用的執行緒池,程式可以將定義的Runnable、Callable任務提交到執行緒池當中執行,由執行緒池負責非同步執行其中的任務。
Java執行緒池框架結構圖: 其中,Executors是一個執行緒池靜態工廠類,可以呼叫其中的靜態方法獲取一些常用的執行緒池實現類。Executors的內部類DelegatedExecutorService採用了裝飾者設計模式,其內部持有一個ExecutorService的實現類。
ThreadPoolExecutor是Java併發工具包中非常常用的一個執行緒池,在我們通過呼叫Executors類的newCachedThreadPool、newSingleThreadExecutor、newFixedThreadPool返回的執行緒池其實都是ThreadPoolExecutor。
ThreadPoolExecutor的public方法及其作用:
方法簽名 | 作用 |
---|---|
void execute(Runnable) | 提交一個Runnable任務到執行緒池任務佇列,等待執行 |
void shutdown() | 執行緒池不再接受新的任務,並將已有的任務執行完畢後關閉執行緒池 |
List<Runnable> shutdownNow() | 立刻關閉執行緒池,正在執行的任務會被interrupt,返回尚未被執行的任務集合 |
boolean isShutdown() | 返回執行緒池是否已經被關閉 |
boolean isTerminating() | 返回執行緒池是否正在被關閉 |
boolean isTerminated() | 返回執行緒池是否已經徹底被關閉 |
boolean awaitTermination(long, TimeUnit) | 使當前執行緒阻塞到執行緒池完全被關閉或者超時 |
void setThreadFactory(ThreadFactory)throws InterruptedException | 重新設定執行緒池的執行緒工廠 |
ThreadFactory getThreadFactory() | 獲取執行緒池的執行緒工廠 |
void setRejectedExecutionHandler(RejectedExecutionHandler) | 設定飽和策略處理器,當任務佇列滿了後提交的任務由這個處理器處理 |
RejectedExecutionHandler getRejectedExecutionHandler() | 獲得該執行緒池的飽和策略處理器 |
void setCorePoolSize(int) | 重新設定執行緒池最低執行緒(核心執行緒)數量 |
int getCorePoolSize() | 獲得該執行緒池的最低執行緒數量 |
boolean prestartCoreThread() | 預先啟動一個核心執行緒 |
int prestartAllCoreThreads() | 預先啟動所有核心執行緒,返回啟動的執行緒數量 |
boolean allowsCoreThreadTimeOut() | 返回核心執行緒是否會因為等待超時而被回收 |
void allowCoreThreadTimeOut(boolean) | 指定核心執行緒會不會因為等待超時而被回收 |
void setMaximumPoolSize(int) | 設定執行緒池最大的活躍執行緒數量 |
int getMaximumPoolSize() | 獲得執行緒池允許的最大執行緒數量 |
void setKeepAliveTime(long, TimeUnit) | 設定執行緒被回收前的最長空閒時間 |
long getKeepAliveTime(TimeUnit) | 獲得執行緒被回收前的最長空閒時間 |
BlockingQueue<Runnable> getQueue() | 獲得該執行緒池的任務佇列引用 |
boolean remove(Runnable) | 從任務佇列中移除指定的任務,返回是否移除成功 |
void purge() | 移除任務佇列中所有的已經被取消掉的Future任務 |
int getPoolSize() | 獲取當前執行緒池的執行緒數量 |
int getActiveCount() | 獲取當前執行緒池正在執行任務的執行緒數量 |
int getLargestPoolSize() | 獲取執行緒池曾經達到的最大執行緒數量 |
long getTaskCount() | 返回該執行緒池執行過的任務數量加上任務佇列中尚未執行的任務(近似值) |
long getCompletedTaskCount() | 返回該執行緒池執行過的任務數量(近似值) |
二、原始碼解析
下面是ThreadPoolExecutor的類定義和例項變數:
public class ThreadPoolExecutor extends AbstractExecutorService {
//執行緒池執行狀態和執行緒數量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//任務佇列,存放被提交的任務
private final BlockingQueue<Runnable> workQueue;
//私有鎖,保證執行緒池併發安全
private final ReentrantLock mainLock = new ReentrantLock();
//儲存執行執行緒的Set集合
private final HashSet<Worker> workers = new HashSet<Worker>();
//私有鎖對應的Condition,用來實現執行緒的等待和喚醒
private final Condition termination = mainLock.newCondition();
//執行緒池執行期間達到過的最大執行緒數量
private int largestPoolSize;
//已完成的任務總數
private long completedTaskCount;
//執行緒工廠,負責構造執行緒例項
private volatile ThreadFactory threadFactory;
//飽和策略處理器,當任務佇列已滿時,提交的任務會由這個處理器處理
private volatile RejectedExecutionHandler handler;
//非核心執行緒最大存活時間(單位:納秒),超出這個時間執行緒物件會被回收
private volatile long keepAliveTime;
//是否允許核心執行緒超時後被回收
private volatile boolean allowCoreThreadTimeOut;
//執行緒池最小執行緒數量(即核心執行緒數量)
private volatile int corePoolSize;
//執行緒池最大執行緒數量
private volatile int maximumPoolSize;
//安全管理器(隸屬java.security包)
private final AccessControlContext acc;
}
每個ThreadPoolExecutor維護了一個原子變數ctl,ctl中儲存了執行緒池的執行狀態和目前持有的執行緒數量:
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
原子變數ctl高3位負責儲存執行狀態,低29位儲存執行緒的數量,可通過位運算提取其中的數值。 從上面的靜態常量可以看出,執行緒池一共有5個狀態: RUNNING:當前執行緒池正在執行 SHUTDOWN:當前執行緒池被掛起(呼叫shutdown方法) STOP:當前執行緒池被停止(呼叫shutdownNow方法) TIDYING:所有任務已經被終止,並且執行緒池擁有的執行緒數量為0 TERMINATED:執行緒池徹底被終止(terminated方法已被呼叫)
1、構造方法
執行緒池提供了4個public構造方法,這幾個構造方法其實相當於1個:
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.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
這個構造方法一共有7個引數,其含義如下:
引數名 | 引數型別 | 含義 |
---|---|---|
corePoolSize | int | 該執行緒池的核心執行緒數量,即最小執行緒數量 |
maximumPoolSize | int | 該執行緒池所允許的最大執行緒數量 |
keepAliveTime | long | 非核心執行緒的最大空閒生存時間,超出這個時間後會被回收 |
unit | TimeUnit | 上述生存時間的時間單位 |
workQueue | BlockingQueue<Runnable> | 該執行緒池存放任務的任務佇列 |
threadFactory | ThreadFactory | 執行緒工廠,執行緒池需要執行緒物件時由它負責建立 |
handler | RejectedExecutionHandler | 當任務佇列已滿無法接受新的任務時,由它負責對這個任務進行處理 |
構造方法的作用基本上就是給成員變數指定初始值,構造結束後,執行緒池中的執行緒數量為0,只有當提交了任務後,執行緒池才會真正執行起來。 其它構造方法:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
這個構造方法會指定預設的執行緒工廠和預設的飽和處理器。
2、執行緒工廠
ThreadPoolExecutor執行緒池通過執行緒工廠(ThreadFactory)來獲取執行緒的例項,以達到非同步執行任務的目的。 執行緒工廠需要實現ThreadFactory介面,該介面只定義了一個方法:
public Thread newThread(Runnable r);
即通過任務物件r返回一個執行緒例項。
通過呼叫Executors的靜態方法defaultThreadFactory,可以獲得一個靜態工廠的實現類,這個實現類是Executors的靜態內部類DefaultThreadFactory:
static class DefaultThreadFactory implements ThreadFactory {
//執行緒池序列號,用於指定執行緒物件的名稱
private static final AtomicInteger poolNumber = new AtomicInteger(1);
//生產出來的執行緒所屬的執行緒組
private final ThreadGroup group;
//執行緒序列號,用於指定執行緒物件的名稱
private final AtomicInteger threadNumber = new AtomicInteger(1);
//執行緒物件名稱字首
private final String namePrefix;
DefaultThreadFactory() {
//獲得安全管理器
SecurityManager s = System.getSecurityManager();
//如果安全管理器不為null的話通過安全管理器指定執行緒組,否則設定為當前執行緒的執行緒組
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
//設定名稱字首,比如"pool-1-thread-"
namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-";
}
public Thread newThread(Runnable r) {
//構造一個新的執行緒物件,指定執行緒組、Runnable任務、執行緒名
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
//將執行緒物件設為非後臺(守護)執行緒
if (t.isDaemon())
t.setDaemon(false);
//將執行緒的優先順序設為一般優先順序
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
預設的執行緒工廠只是給執行緒物件指定一個名稱和Runnable任務,並將其設為非守護執行緒和一般優先順序。 當我們呼叫Executors類的newCachedThreadPool、newFixedThreadPool、newSingleThreadExecutor時,其執行緒工廠都會預設設定為它。
3、飽和策略
ThreadPoolExecutor定義了4種RejectedExecutionHandler實現類,分別是AbortPolicy、CallerRunsPolicy、DiscardPolicy、DiscardOldestPolicy,這些都是ThreadPoolExecutor的public許可權的非final靜態內部類,代表著4種飽和策略。 下面通過程式碼來介紹這幾種自帶的飽和策略:
public static class AbortPolicy implements RejectedExecutionHandler {
public AbortPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString());
}
}
AbortPolicy(中止策略)是ThreadPoolExecutor的預設飽和策略,該策略將丟擲未檢查的RejectedExecutionException異常。呼叫者可以選擇捕獲該異常並根據自己的需求編寫處理的程式碼。
public static class CallerRunsPolicy implements RejectedExecutionHandler {
public CallerRunsPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
//由當前執行緒執行任務
r.run();
}
}
}
CallerRunsPolicy(呼叫者執行策略):該策略既不會拋棄任務,也不會丟擲異常,而是將任務回退給呼叫者(比如回退給main執行緒,由main執行緒自行處理)。
public static class DiscardPolicy implements RejectedExecutionHandler {
public DiscardPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { /*啥也不做*/ }
}
DiscardPolicy(拋棄策略):當工作佇列已滿並無法新增,拋棄策略會扔掉該任務,什麼也不做。
public static class DiscardOldestPolicy implements RejectedExecutionHandler {
public DiscardOldestPolicy() { }
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
//從任務佇列取出隊首元素
e.getQueue().poll();
//重新將任務新增
e.execute(r);
}
}
}
DiscardOldestPolicy(拋棄最舊任務策略):該策略會拋棄任務佇列隊首的任務並嘗試重新提交新的任務,如果任務佇列是優先佇列,那麼將拋棄優先順序最高的佇列(所以不要和優先佇列同時使用)。
除此之外,使用者還可以自定義飽和處理器,只需要在構造階段指定飽和處理器或者通過setRejectedExecutionHandle方法指定。
4、任務的提交
使用者可以通過executor方法向執行緒池提交一個Runnable任務
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//獲取執行緒池的狀態和執行緒數量
int c = ctl.get();
//如果目前的執行緒數量小於核心執行緒數量
if (workerCountOf(c) < corePoolSize) {
//生產一個執行緒,並執行任務
if (addWorker(command, true))
return;
c = ctl.get();
}
//如果執行緒池正在執行並且成功將任務新增至佇列
if (isRunning(c) && workQueue.offer(command)) {
//再次獲取ctl
int recheck = ctl.get();
//如果執行緒池此時停止,那麼從任務佇列移除這個任務,並轉交給飽和處理器處理
if (!isRunning(recheck) && remove(command))
reject(command);
//如果執行緒池沒有停止,那麼如果判斷執行緒池執行緒數量為0的話,就向執行緒池新增一個執行緒物件
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//新增執行緒並執行任務,如果沒有成功,那麼轉交給飽和處理器處理
else if (!addWorker(command, false))
reject(command);
}
execute方法執行步驟如下: 1、如果執行緒池目前擁有的執行緒數量小於核心執行緒數量,那麼呼叫addWorker方法向執行緒池新增一個執行緒並執行這個任務,操作成功後execute方法結束。 2、否則,就將這個任務物件新增到任務佇列,如果執行緒池停止執行或者任務已滿,那麼呼叫reject方法將這個任務物件轉交給飽和處理器處理。另外如果執行緒池沒有停止並且執行緒數量為0的話,execute方法會向執行緒池新增一個執行緒。
addWorker方法的原始碼:
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
//執行緒進入自旋
for (;;) {
int c = ctl.get();
//獲取執行狀態
int rs = runStateOf(c);
//如果執行緒池停止,那麼返回false
if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && !workQueue.isEmpty()))
return false;
for (;;) {
//獲取執行緒池的執行緒數量
int wc = workerCountOf(c);
//如果執行緒數量超出執行緒池允許的最大執行緒數量(或者當core為true時超出核心執行緒數量),則返回false
if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//增加執行緒數量,如果增加成功,跳出retry塊
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get();
//如果執行緒池狀態發生改變,則從retry塊開始
if (runStateOf(c) != rs)
continue retry;
}
}
//執行緒是否成功啟動
boolean workerStarted = false;
//是否成功新增到執行緒集合中
boolean workerAdded = false;
Worker w = null;
try {
//建立一個Worker(相當於一個執行緒)
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
//獲取私有鎖並加鎖,保證執行緒安全
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//獲取執行緒池狀態
int rs = runStateOf(ctl.get());
//如果執行緒池正在執行
if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) {
//如果執行緒已經在執行,丟擲IllegalThreadStateException
if (t.isAlive())
throw new IllegalThreadStateException();
//向儲存Worker的HashSet新增這個Worker
workers.add(w);
int s = workers.size();
//如果當前執行緒數量超出曾經達到的最大執行緒數量的話,更新這個值
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
//如果成功地將Worker新增到集合中,那麼啟動這個執行緒
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
reject方法比較簡單,直接獲取ThreadPoolExecutor指定的飽和處理器並執行
final void reject(Runnable command) {
//呼叫飽和處理器的rejectExecution處理這個任務
handler.rejectedExecution(command, this);
}
execute方法的過程可以用流程圖表示如下:
5、任務的執行
每個提交的任務都由執行緒池中的執行緒負責執行。 ThreadPoolExecutor定義了一個非靜態內部類:Worker,每個Worker例項表示一個執行緒 執行緒池通過將執行緒封裝為一個Worker物件,儲存線上程池的HashSet型別的成員變數workers中:
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
//工作執行緒
final Thread thread;
//第一個任務物件
Runnable firstTask;
//這個執行緒已經完成的任務數量
volatile long completedTasks;
Worker(Runnable firstTask) {
//將AQS的state狀態設為-1,表示必須要首先呼叫release方法
setState(-1);
this.firstTask = firstTask;
//通過執行緒池的執行緒工廠獲取執行緒物件
this.thread = getThreadFactory().newThread(this);
}
public void run() {
//呼叫外部類的runWorker方法執行任務
runWorker(this);
}
//省略其它方法
}
Worker持有三個例項變數:執行任務的執行緒物件、第一個執行的任務物件(僅用於這個執行緒執行的第一個任務)和這個Wokrer已經執行完成的任務數量。 Worker繼承了AQS類,是為了能夠判斷Worker是否在執行任務,並能夠使Worker在執行完任務後繼續執行下一個任務。Worker重寫了AQS的tryAcquire、tryRelease、isHeldExclusively方法,可以通過state變數的值來判定Worker的狀態。
對於AQS的實現類Worker來說,其state變數含義如下: state為-1時,該Worker處於初始化狀態,即還沒有開始執行第一個任務。 state為0時,該Worker正在從任務佇列獲取任務,或者正準備執行第一個任務。 state為1時,該Worker正在執行任務。
//如果AQS的state狀態不為0,則持有鎖
protected boolean isHeldExclusively() {
return getState() != 0;
}
//嘗試獲取鎖
protected boolean tryAcquire(int unused) {
//通過CAS將state由0設為1,成功後表示成功獲得鎖
if (compareAndSetState(0, 1)) {
//將鎖的持有執行緒設定為當前執行緒
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
//釋放鎖,這裡只會返回true
protected boolean tryRelease(int unused) {
//清除持有鎖的執行緒並將state設為0
setExclusiveOwnerThread(null);
setState(0);
return true;
}
//加鎖
public void lock() { acquire(1); }
相關推薦
Java執行緒池之ThreadPoolExecutor原始碼分析
一、引言
Java併發工具包自帶了很多常用的執行緒池,程式可以將定義的Runnable、Callable任務提交到執行緒池當中執行,由執行緒池負責非同步執行其中的任務。
Java執行緒池框架結構圖:
其中,Executors是一個執行緒池靜態工廠類,可以呼叫其
java執行緒池之ThreadPoolExecutor(二):任務入佇列和任務丟棄
一、關於任務入佇列
在上一篇【java執行緒池之ThreadPoolExecutor(一)】中,
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,
java執行緒池之ThreadPoolExecutor(三):提交任務並得到任務執行結果
1.Callable<V>介面
ThreadPoolExecutor不僅可以執行Runnable的實現類,還可以執行Callable介面的實現類。Callable的介面和Runnable介面的區別是:Callable有一個call方法能夠得到任務執行結果,而Ru
JUC(4)---java執行緒池原理及原始碼分析
執行緒池,既然是個池子裡面肯定就裝很多執行緒。
如果併發的請求數量非常多,但每個執行緒執行的時間很短,這樣就會頻繁的建立和銷燬 執行緒,如此一來會大大降低系統的效率。可能出現伺服器在為每個請求建立新執行緒和銷燬線 程上花費的時間和消耗的系統資源要比處理實際的使用者請求的時間和資源更多。因此Java中提供執行緒
執行緒池之ThreadPoolExecutor執行緒池原始碼分析筆記
1.執行緒池的作用
一方面當執行大量非同步任務時候執行緒池能夠提供較好的效能,在不使用執行緒池的時候,每當需要執行非同步任務時候是直接 new 一執行緒進行執行,而執行緒的建立和銷燬是需要開銷的。使用執行緒池時候,執行緒池裡面的執行緒是可複用的,不會每次執行非同步任務時候都重新建立和銷燬執行緒。
另一方面
Java併發程式設計:Java執行緒池核心ThreadPoolExecutor的使用和原理分析
引出執行緒池
執行緒是併發程式設計的基礎,前面的文章裡,我們的例項基本都是基於執行緒開發作為例項,並且都是使用的時候就建立一個執行緒。這種方式比較簡單,但是存在一個問題,那就是執行緒的數量問題。
假設有一個系統比較複雜,需要的執行緒數很多,如果都是採用這種方式來建立執行緒的話,那麼就會極大的消耗系統資源。
JAVA執行緒池(ThreadPoolExecutor)原理分析與使用
在我們的開發中,“池”的概念並不罕見,有資料庫連線池、執行緒池、物件池、常量池等。下面我們主要針對執行緒池來一步一步揭開執行緒池的面紗。
使用執行緒池的好處
(1)降低資源消耗
可以重複利用自己建立的執行緒降低執行緒建立和銷燬造成的消耗。
(2)提高響應速度
當任務到達時
執行緒池之ThreadPoolExecutor
目錄
1.ThreadPoolExecutor建構函式
2.BlockingQueue workQueue引數詳解
3.ThreadPoolExecutor執行任務demo
4.利用submit去提交任務
5.自定義ThreadPoolExecutor
上一篇說了多執行緒
【小家java】Java執行緒池之---ForkJoinPool執行緒池的使用以及原理
相關閱讀
【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9
java執行緒池之PrivilegedThreadFactory
這個類的原始碼如下:
static class PrivilegedThreadFactory extends DefaultThreadFactory {
private final AccessControlContext acc;
Java執行緒池之柵欄
通過閉鎖來啟動一組相關的操作,或者等待一組相關的操作結束。閉鎖是一次性物件,一旦進入終止狀態,就不能重置。
柵欄類似於閉鎖,它能阻塞到一組執行緒到某個事件發生。柵欄於閉鎖的關鍵區別在於,所有執行緒必須同時到達柵欄位置,才能繼續執行。閉鎖用於等待事件,而柵欄用於等待其他執行緒。柵欄
jdk自帶的執行緒池框架ThreadPoolExcutor原始碼分析
一、前言
JUC這部分還有執行緒池這一塊沒有分析,需要抓緊時間分析,下面開始ThreadPoolExecutor,其是執行緒池的基礎,分析完了這個類會簡化之後的分析,執行緒池可以解決兩個不同問題:由於減少了每個任務呼叫的開銷,它們通常可以在執行大量非同步任務
JAVA執行緒池,ThreadPoolExecutor實現的四種執行緒池
執行緒池在JAVA中,我們使用執行緒的時候就去建立一個執行緒,這樣實現起來非常簡便。但是就會有一個問題,如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒就會大大降低系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間。那麼有沒有一種
Java執行緒池execute()方法原始碼解析
先看作者給出的註釋來理解執行緒池到底有什麼作用
* Thread pools address two different problems: they usually* provide improved performance when executing large nu
執行緒池之ThreadPoolExecutor使用
ThreadPoolExecutor提供了四個構造方法:
&
JAVA執行緒池(ThreadPoolExecutor)原始碼分析
中使用ThreadPoolExecutor的常用方式:
例項程式碼1
Java程式碼
Runnable runnable = new CountService(intArr); ThreadPoolExecutor execute = (T
深入原始碼分析Java執行緒池的實現原理
程式的執行,其本質上,是對系統資源(CPU、記憶體、磁碟、網路等等)的使用。如何高效的使用這些資源是我們程式設計優化演進的一個方向。今天說的執行緒池就是一種對CPU利用的優化手段。
網上有不少介紹如何使用執行緒池的文章,那我想說點什麼呢?我希望通過學習執行緒池原理,明白所有
Java執行緒池ThreadPoolExecutor使用和分析(二)
相關文章目錄:
execute()是 java.util.concurrent.Executor介面中唯一的方法,JDK註釋中的描述是“在未來的某一時刻執行命令command”,即向執行緒池中提交任務,在未來某個時刻執行,提交的任務必須實現
jdk1.7的Java執行緒池架構原理和原始碼解析(ThreadPoolExecutor)
我們現在來看看ThreadPoolExecutor的原始碼是怎麼樣的,也許你剛開始看他的原始碼會很痛苦,因為你不知道作者為什麼是這樣設計的,所以本文就我看到的思想會給你做一個介紹,此時也許你通過知道了一些作者的思想,你也許就知道應該該如何去操作了。
這裡來看下構造方法中對那
併發程式設計(十二)—— Java 執行緒池 實現原理與原始碼深度解析 之submit方法 (二)
在上一篇《併發程式設計(十一)—— Java 執行緒池 實現原理與原始碼深度解析(一)》中提到了執行緒池ThreadPoolExecutor的原理以及它的execute方法。這篇文章是接著上一篇文章寫的,如果你沒有閱讀上一篇文章,建議你去讀讀。本文解析ThreadPoolExecutor#submit。