【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )
文章目錄
- 一、線程池簡介
- 二、線程池初始化方法簡介
- 三、線程池使用示例
一、線程池簡介
線程池一般是實現了 ExecutorService 接口的類 , 一般使用 ThreadPoolExecutor 線程池 ;
線程池優勢 :
減少線程對象個數 : 避免每次執行子線程任務時 , 都要執行 new Thread() 構造函數 , 避免每次創建一個新的對象 , 減少開銷 ;
線程管理 : 方面對線程進行管理 , 已存在的線程直接重用 , 這樣減少了線程對象創建的個數 , 降低了 CPU 資源開銷 ;
控制并發數 : 每個 CPU 都有最合適的并發線程數 , 如果并發數過高 , 就會導致資源競爭 , 線程堵塞 , 合理控制并發數 , 能提高 CPU 使用效率 ;
二、線程池初始化方法簡介
線程池初始化方法簡介 :
newCachedThreadPool : 創建 可緩存線程池 ; 如果線程池長度超過處理需要 , 則回收線程 , 如果不能回收 , 就創建新線程 ;
newFixedThreadPool : 創建 定長線程池 ; 可以設置線程最大并發數 , 如果并發數已滿 , 后續任務會在任務隊列中等待 ;
newScheduledThreadPool : 創建 定長周期任務線程池 ; 該線程池支持周期性任務執行 ;
newSingleThreadExecutor : 創建 單線程化線程池 ; 該線程只有一個工作線程 , 可以保證所有任務按照指定的順序執行 ; 如 FIFO 先進先出順序 , 或 LIFO 后進先出順序 ;
三、線程池使用示例
以 AsyncTask 源代碼為例 , 在 SerialExecutor 中 , 最終使用的是 THREAD_POOL_EXECUTOR.execute(mActive) 執行線程任務 ; 線程池通過 execute 函數執行外部任務 ;
THREAD_POOL_EXECUTOR 是 自己配置的線程池 , 沒有使用 Java 默認提供的四種線程池 , Java 提供的四種線程池是 可緩存線程池 , 定長線程池 , 定長周期任務線程池 , 單線程線程池 ;
THREAD_POOL_EXECUTOR 線程池配置代碼如下 :
new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,new ThreadPoolExecutor.DiscardOldestPolicy());下面對 THREAD_POOL_EXECUTOR 自己配置的線程池參數進行說明解析 ,
CORE_POOL_SIZE 核心線程數 ,
MAXIMUM_POOL_SIZE 最大線程數 , 非核心線程就是二者相減 ,
KEEP_ALIVE 非核心線程閑置時間 , 超過一定時間非核心線程就會回收 ,
TimeUnit.SECONDS 非核心線程閑置時間單位 “秒” ,
sPoolWorkQueue 線程池任務隊列 ,
sThreadFactory 線程工廠 , 作用是用于創建線程
線程池原理說明 :
線程池線程分類 : 線程池的線程分為 核心線程 , 非核心線程 兩類 ;
非核心線程閑置時間 : 非核心線程 超過一定的閑置時間 , 就會被回收 ;
假設線程池最大線程數是 888 , 核心線程數 333 , 非核心線程數 555 ;
線程池任務隊列 : 當啟動一個線程池后 , 線程池會不停地從該任務隊列中取出任務執行 ,
-
啟動核心線程 : 如果當前核心線程沒有滿 , 小于 333 個 , 那么創建核心線程執行該任務 ,
-
啟動非核心線程 : 如果當前核心線程已經有 333 個 , 但是 非核心線程沒有滿 , 小于 555 個 , 那么會創建非核心線程 , 執行該任務 ;
執行者 Executor 執行任務處理 : 如果核心線程數 有 333 個 , 非核心線程數有 555 個 , 最大線程數已滿 ; 如果用戶再提交任務給線程池 , 就會 將任務放入線程池任務隊列中排隊 ; 如果此時任務隊列也滿了 , 此時就會 拋出異常 ; 開發者應該通過回調處理被拒絕的任務 ;
線程池從任務隊列取出任務并執行 : 線程數量 CCC
- 線程數量 C<3C < 3C<3 : 創建核心線程執行任務 ;
- 線程數量 3≤C<83 \leq C < 83≤C<8 : 創建非核心線程執行任務 ;
用戶調用 Executor 的 execute 執行任務 : 線程數量 CCC
- 線程數 C=8C = 8C=8 , 任務隊列沒滿 : 將任務放入任務隊列 ;
- 線程數 C=8C = 8C=8 , 任務隊列已滿 : 會報出異常 , 使用 Handler 處理錯誤 ;
/*** 創建自定義線程池 , 用于并行執行任務 .*/public static final Executor THREAD_POOL_EXECUTOR= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory,new ThreadPoolExecutor.DiscardOldestPolicy());/*** 一個 Executor 執行者 , 以串行順序 , 一次執行一個任務 ; 針對特定進行 , 該序列化是全局的 , * 即 一個進程只有一個該執行者 . */public static final Executor SERIAL_EXECUTOR = Utils.hasHoneycomb() ? new SerialExecutor() :Executors.newSingleThreadExecutor(sThreadFactory);@TargetApi(11)private static class SerialExecutor implements Executor {final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();Runnable mActive;public synchronized void execute(final Runnable r) {mTasks.offer(new Runnable() {public void run() {try {r.run();} finally {scheduleNext();}}});if (mActive == null) {scheduleNext();}}protected synchronized void scheduleNext() {if ((mActive = mTasks.poll()) != null) {THREAD_POOL_EXECUTOR.execute(mActive);}}}
總結
以上是生活随笔為你收集整理的【Android 异步操作】线程池 ( 线程池简介 | 线程池初始化方法 | 线程池种类 | AsyncTask 使用线程池示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【组合数学】指数生成函数 ( 指数生成函
- 下一篇: 【Android 异步操作】线程池 (