Android高併發問題處理和執行緒池ThreadPool執行緒池原始碼分析
Android實現高效能,高併發,可延時執行緒池管理
為什麼要使用執行緒池?
1.)new Thread()的缺點
每次new Thread()耗費效能
呼叫new Thread()建立的執行緒缺乏管理,被稱為野執行緒,而且可以無限制建立,之間相互競爭,會導致過多佔用系統資源導致系統癱瘓。
不利於擴充套件,比如如定時執行、定期執行、執行緒中斷
2.)採用執行緒池的優點
重用存在的執行緒,減少物件建立、消亡的開銷,效能佳
可有效控制最大併發執行緒數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞
提供定時執行、定期執行、單執行緒、併發數控制等功能
執行緒池相關類的繼承關係:
Executor<--ExecutorService<--AbstractExecutorService<--ThreadPoolExecutor
Executors可以生成快捷的執行緒池,ThreadPoolExecutor完全自定義執行緒池
原始碼ThreadPoolExecutor分析
自定義執行緒池工具ThreadManager(在本文章後面)
建立了執行緒代理new ThreadPoolProxy()
作用:替換new Thread()的執行緒
使用方式:
ThreadManager.getNormalPool().execute(Runnable物件);//普通執行緒池
ThreadManager.getDownloadPool().execute(Runnable物件);//下載專用執行緒池
ThreadManager.getXxxxxPool().remove(Runnable物件);//移除任務(停止執行緒池執行)
使用執行緒池的好處:
1.降低資源消耗:通過重用已經建立的執行緒來降低執行緒建立和銷燬的消耗
2.提高響應速度:任務到達時不需要等待執行緒建立就可以立即執行。
3.提高執行緒的可管理性:執行緒池可以統一管理、分配、調優和監控
原始碼分析:構造方法
public ThreadPoolExecutor(int corePoolSize, //核心執行緒池大小
int maximumPoolSize,//執行緒池最大容量大小
long keepAliveTime,//執行緒池空閒時,執行緒存活的時間
TimeUnit unit,//時間單位
BlockingQueue<Runnable> workQueue,//任務佇列
ThreadFactory threadFactory,//執行緒工廠
RejectedExecutionHandler handler) //執行緒拒絕策略{....}
//當前的Worker的數量小於核心執行緒池大小時,新建一個Worker。
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
(1).corePoolSize:設定一個執行緒池中的核心執行緒數
如果設定allowCoreThreadTimeOut為false的情況下:
即使當執行緒池中的執行緒處於空閒狀態,這些執行緒也不會被執行緒池中移除。
如果設定了allowCoreThreadTimeOut為true,
那麼當核心執行緒在空閒了一段時間後依舊沒有用於工作,那麼將會從執行緒池中移除。
注意:(allowCoreThreadTimeOut預設為false,通常情況下也無需做修改)
(2).maximumPoolSize:執行緒池中所允許建立最大執行緒數量
(3).keepAliveTime:當執行緒池中的執行緒數量大於核心執行緒數,
如果這些多出的執行緒在經過了keepAliveTime時間後,
依然處於空閒狀態,那麼這些多出的空閒執行緒將會被結束其生命週期。
(4).unit:keepAliveTime的時間單位
(5).workQueue:執行緒池的快取佇列//用於存放任務的阻塞佇列,當執行緒池中的核心執行緒都處在執行任務時,
提交的任務將被儲存在workQueue進行緩衝。
該佇列只能存放通過execute方法提交的Runnable任務。
(6).threadFactory:執行緒池中用於建立執行緒的工廠
在這裡使用執行緒工廠的目的也是為了解耦,將建立的實現細節通過工廠進行封裝,
而不是直接將建立的方式固化在ThreadPoolExecutor本身的程式碼中。
Thread newThread(Runnable r)
(7)RejectedExecutionHandler:執行緒池對拒絕任務的處理策略.
當執行緒池中的執行緒數量達到最大並且阻塞佇列也已經滿了無法再新增任務時,執行緒池所採取的處理策略。
核心方法:addWorker
addWorker(Runnable firstTask, boolean core)
總結執行緒池任務提交的過程:
如果執行緒池中實際的執行緒數量小於corePoolSize核心執行緒數,那麼就啟動一個新的執行緒進行任務的處理。
如果執行緒池中實際的執行緒數量大於等於corePoolSize核心核心執行緒數,則將任務放置到任務佇列中進行處理。
如果由於任務佇列已經滿了,無法再存放新的任務,則判斷執行緒池中實際的執行緒數量是否大於maximumPoolSize執行緒池最大容量:
如果小於,則建立新的執行緒執行.
否則將拒絕執行任務RejectedExecutionHandler.
ThreadPoolExecutor的其他知識點
關閉執行緒池
兩個方法:shutdownNow()和shutdown().
ThreadPoolExecutor預設有四個拒絕策略
1、ThreadPoolExecutor.AbortPolicy() 直接丟擲異常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy() 直接呼叫run方法並且阻塞執行
3、ThreadPoolExecutor.DiscardPolicy() 直接丟棄後來的任務
4、ThreadPoolExecutor.DiscardOldestPolicy() 丟棄在佇列中隊首的任務
官方定義的四種執行緒池
1、FixedThreadPool,數量固定的執行緒池,且任務佇列也沒有大小限制;
只有核心執行緒,且這裡的核心執行緒也沒有超時限制,因為它不會被回收,所以它能更快的響應
2、CachedThreadPool
執行緒數量不固定的執行緒池;可以進行自動執行緒回收,只有非核心執行緒,且最大執行緒數為Integer.MAX_VALUE
適合做大量的耗時較少的任務
3、SingleThreadExecutor
只有一個核心執行緒,所有任務都在同一執行緒中按序執行,這樣也就不需要處理執行緒同步的問題.
4、ScheduledThreadPool
它的核心執行緒數量是固定的,而非核心執行緒是沒有限制的,且非核心執行緒空閒時會被回收;適合執行定時任務和具有固定週期的任務
shutdown做了幾件事:
1. 檢查是否能操作目標執行緒
2. 將執行緒池狀態轉為SHUTDOWN
3. 中斷所有空閒執行緒
但是隻是清除一些空閒Worker,並且拒絕新Task加入,對於workQueue中的執行緒還是繼續處理的。
STOP
拒絕所有新Task的加入,同時中斷所有執行緒,WorkerQueue中沒有執行的執行緒全部拋棄。
所以此時Pool是空的,WorkerQueue也是空的
Worker和Task的區別
Worker是當前執行緒池中的執行緒,而task雖然是runnable,但是並沒有真正執行,只是被Worker呼叫了run方法,後面會看到這部分的實現。
maximumPoolSize和corePoolSize的區別:
maximumPoolSize為執行緒池最大容量,也就是說執行緒池最多能起多少Worker。
corePoolSize是核心執行緒池的大小,當corePoolSize滿了時,
同時workQueue full(ArrayBolckQueue是可能滿的) 那麼此時允許新建Worker去處理workQueue中的Task,但是不能超過maximumPoolSize。
超過corePoolSize之外的執行緒會在空閒超時後終止。
最後附上自定義的執行緒池封裝工具ThreadManager
使用方式:
ThreadManager.getNormalPool().execute(Runnable物件);//普通執行緒池
ThreadManager.getDownloadPool().execute(Runnable物件);//下載專用執行緒池
ThreadManager.getXxxxxPool().remove(Runnable物件);//移除任務(停止執行緒池執行)
/**執行緒管理類,管理執行緒池,一個應用中有多個執行緒池,每個執行緒池做自己相關的業務*/
public class ThreadManager {
private static ThreadPoolProxy mNormalPool = new ThreadPoolProxy(1, 3, 5 * 1000);
private static ThreadPoolProxy mDownloadPool = new ThreadPoolProxy(3, 3, 5 * 1000);
public static ThreadPoolProxy getNormalPool() {
return mNormalPool;
}
public static ThreadPoolProxy getDownloadPool() {
return mDownloadPool;
}
public static class ThreadPoolProxy {
private final int mCorePoolSize;
private final int mMaximumPoolSize;
private final long mKeepAliveTime;
private ThreadPoolExecutor mPool;
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
this.mCorePoolSize = corePoolSize;
this.mMaximumPoolSize = maximumPoolSize;
this.mKeepAliveTime = keepAliveTime;
}
private void initPool() {
if (mPool == null || mPool.isShutdown()) {
// int corePoolSize = 1;//核心執行緒池大小
// int maximumPoolSize = 3;//最大執行緒池大小
// long keepAliveTime = 5 * 1000;//保持存活的時間
TimeUnit unit = TimeUnit.MILLISECONDS;//單位
BlockingQueue<Runnable> workQueue = null;//阻塞佇列
workQueue = new ArrayBlockingQueue<Runnable>(4);//FIFO,大小有限制
// workQueue = new LinkedBlockingQueue();//
// workQueue = new PriorityBlockingQueue();
ThreadFactory threadFactory = Executors.defaultThreadFactory();//執行緒工廠
RejectedExecutionHandler handler = null;//異常捕獲器
// handler = new ThreadPoolExecutor.DiscardOldestPolicy();//去掉佇列中首個任務,將新加入的放到佇列中去
// handler = new ThreadPoolExecutor.AbortPolicy();//觸發異常
handler = new ThreadPoolExecutor.DiscardPolicy();//不做任何處理
// handler = new ThreadPoolExecutor.CallerRunsPolicy();//直接執行,不歸執行緒池控制,在呼叫執行緒中執行
// new Thread(task).start();
mPool = new ThreadPoolExecutor(mCorePoolSize,
mMaximumPoolSize,
mKeepAliveTime,
unit,
workQueue,
threadFactory,
handler);
}
}
/**
* 執行任務
*
* @param task
*/
public void execute(Runnable task) {
initPool();
//執行任務
mPool.execute(task);
}
public Future<?> submit(Runnable task) {
initPool();
return mPool.submit(task);
}
public void remove(Runnable task) {
if (mPool != null && !mPool.isShutdown()) {
mPool.getQueue()
.remove(task);
}
}
}
}
相關文章
- ThreadPool執行緒池thread執行緒
- 執行緒池之ScheduledThreadPoolExecutor執行緒池原始碼分析筆記執行緒thread原始碼筆記
- 執行緒池之ThreadPoolExecutor執行緒池原始碼分析筆記執行緒thread原始碼筆記
- 執行緒池原始碼分析執行緒原始碼
- Java 併發:執行緒、執行緒池和執行器全面教程Java執行緒
- 執行緒和執行緒池執行緒
- 執行緒池的建立和使用,執行緒池原始碼初探(篇一)執行緒原始碼
- Android執行緒池Android執行緒
- Android多執行緒之執行緒池Android執行緒
- Python執行緒池ThreadPoolExecutor原始碼分析Python執行緒thread原始碼
- Java-ThreadPool執行緒池總結Javathread執行緒
- Java併發之執行緒池ThreadPoolExecutor原始碼分析學習Java執行緒thread原始碼
- JAVA併發程式設計:執行緒池ThreadPoolExecutor原始碼分析Java程式設計執行緒thread原始碼
- 詳解Java執行緒池的ctl(執行緒池控制狀態)【原始碼分析】Java執行緒原始碼
- 原始碼|從序列執行緒封閉到物件池、執行緒池原始碼執行緒物件
- Netty原始碼解析一——執行緒池模型之執行緒池NioEventLoopGroupNetty原始碼執行緒模型OOP
- 執行緒池原始碼探究執行緒原始碼
- 【高併發】從原始碼角度分析建立執行緒池究竟有哪些方式原始碼執行緒
- 《Java 高階篇》七:執行緒和執行緒池Java執行緒
- Android程式框架:執行緒與執行緒池Android框架執行緒
- 66.QT-執行緒併發、QTcpServer併發、QThreadPool執行緒池QT執行緒TCPServerthread
- Java併發 之 執行緒池系列 (1) 讓多執行緒不再坑爹的執行緒池Java執行緒
- Java併發——執行緒池ThreadPoolExecutorJava執行緒thread
- Java併發系列 — 執行緒池Java執行緒
- 聊聊併發(五)——執行緒池執行緒
- java多執行緒與併發 - 執行緒池詳解Java執行緒
- Java執行緒池二:執行緒池原理Java執行緒
- Java併發 之 執行緒池系列 (2) 使用ThreadPoolExecutor構造執行緒池Java執行緒thread
- 執行緒 執行緒池 Task執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒池執行模型原始碼全解析執行緒模型原始碼
- JDK執行緒池原始碼研究JDK執行緒原始碼
- Java執行緒池和Spring非同步處理高階篇Java執行緒Spring非同步
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- 高併發面試:執行緒池的七大引數?手寫一個執行緒池?面試執行緒
- Java排程執行緒池ScheduledThreadPoolExecutor原始碼分析Java執行緒thread原始碼
- jdk1.8 執行緒池部分原始碼分析JDK執行緒原始碼
- 執行緒池執行緒
- Android中的執行緒池Android執行緒