日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 )

發(fā)布時間:2025/6/17 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、線程池作用
  • 二、線程池種類
  • 三、線程池工作機制
  • 四、線程池任務(wù)調(diào)度源碼解析





一、線程池作用



線程池作用 :

① 避免創(chuàng)建線程 : 避免每次使用線程時 , 都需要 創(chuàng)建線程對象 ;

② 統(tǒng)一管理 : 統(tǒng)一管理線程 , 重用存在的線程 , 減少線程對象創(chuàng)建 , 銷毀的開銷 ;

③ 控制并發(fā) :控制線程的最大并發(fā)數(shù) , 提高資源使用效率 , 避免資源競爭導(dǎo)致堵塞 ;





二、線程池種類



線程池種類 :

① newCachedThreadPool : 可緩存線程池 , 如果 線程池線程個數(shù)已滿 , 回收空閑線程 , 如果沒有空閑線程 , 此時會創(chuàng)建新線程 ;

② newFixedThreadPool : 創(chuàng)建固定大小線程池 , 可設(shè)置并發(fā)數(shù) , 如果并發(fā)數(shù)已滿 , 后續(xù)任務(wù)會 在 等待隊列 中等待可用線程 ;

③ newScheduledThreadPool : 創(chuàng)建固定大小線程池 , 其支持 周期性任務(wù) ;

④ newSingleThreadExecutor : 創(chuàng)建 單線程 線程池 , 該線程池中 只有一個線程 , 所有的任務(wù)按照指定的優(yōu)先級順序執(zhí)行 , 如 FIFO 先入先出 ( 先到的先執(zhí)行 , 后到的后執(zhí)行 ) , LIFO 后入先出 ( 后到的先執(zhí)行 ) ;





三、線程池工作機制



線程池線程相關(guān)概念:

  • 線程數(shù) : 線程池的 有 最大線程數(shù) MaxSzie , 核心線程數(shù) CoreSize , 非核心線程數(shù)就是 MaxSize - CoreSize ;

  • 示例 : 最大線程數(shù) ( MaxSize ) 是 8 個 , 有 3 個核心線程 ( CoreSize ) , 5 個非核心線程 ;

  • 非核心線程 : 閑置超過一定時間 , 就會被回收 ;


線程池任務(wù)調(diào)度 : 線程池中維護了一個任務(wù)隊列 , 線程池啟動后 , 會不停的從任務(wù)隊列中取出任務(wù) , 如果有新任務(wù) , 執(zhí)行如下操作 ;

如果 線程數(shù) 小于核心線程數(shù) ( CoreSize ) , 那么創(chuàng)建核心線程 , 執(zhí)行上述任務(wù) ;

如果 線程數(shù) 大于核心線程數(shù) ( CoreSize ) , 小于最大線程數(shù) ( MaxSize ) , 那么創(chuàng)建非核心線程 , 執(zhí)行上述任務(wù) ;

如果 線程數(shù) 超過 最大線程數(shù) ( MaxSize )

  • 如果 任務(wù)隊列沒滿 , 則將任務(wù)放入任務(wù)隊列 ;
  • 如果 任務(wù)隊列滿了 , 則拋出異常 ; 這里一般情況下需要手動處理這種情況 , 任務(wù)拒絕后 , 處理善后 ;





四、線程池任務(wù)調(diào)度源碼解析



在 AsyncTask.java 中 , 在靜態(tài)代碼塊中 , 自己 自定義創(chuàng)建了線程池 , 沒有使用上述四種線程池 ;


創(chuàng)建線程池時傳入的參數(shù) :

  • CORE_POOL_SIZE : 核心線程數(shù)
  • MAXIMUM_POOL_SIZE : 最大線程數(shù)
  • KEEP_ALIVE_SECONDS : 閑置時間 , 非核心線程一旦閑置超過一定時間 , 就會被回收
  • TimeUnit.SECONDS : 閑置時間單位 , 秒
  • sPoolWorkQueue : 線程隊列 , 任務(wù)隊列
  • sThreadFactory : 線程工廠 , 用于生產(chǎn)線程
public abstract class AsyncTask<Params, Progress, Result> {static {/*** 自定義的線程池 : * CORE_POOL_SIZE : 核心線程數(shù) * MAXIMUM_POOL_SIZE : 最大線程數(shù) * KEEP_ALIVE_SECONDS : 閑置時間 , 非核心線程一旦閑置超過一定時間 , 就會被回收* TimeUnit.SECONDS : 閑置時間單位 , 秒* sPoolWorkQueue : 線程隊列 , 任務(wù)隊列 * sThreadFactory : 線程工廠 , 用于生產(chǎn)線程 */ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,sPoolWorkQueue, sThreadFactory);threadPoolExecutor.allowCoreThreadTimeOut(true);THREAD_POOL_EXECUTOR = threadPoolExecutor;}private static class SerialExecutor implements Executor {protected synchronized void scheduleNext() {if ((mActive = mTasks.poll()) != null) {// 線程池執(zhí)行任務(wù) THREAD_POOL_EXECUTOR.execute(mActive);}}} }

在 AsyncTask 中 , 調(diào)用 ThreadPoolExecutor THREAD_POOL_EXECUTOR 線程池的 void execute(Runnable command) 方法 , 執(zhí)行線程池任務(wù) ;

在 execute 方法中, 需要執(zhí)行以下三個步驟 :

  • 如果當前 運行線程數(shù)小于核心線程數(shù) , 嘗試 啟動新線程執(zhí)行該任務(wù), 該任務(wù)是線程的第一個任務(wù).調(diào)用 addWorker 方法會檢查運行狀態(tài), 和線程運行個數(shù), 避免在不應(yīng)該添加線程時執(zhí)行錯誤操作.

  • 如果 任務(wù)成功加入隊列, 需要 雙重檢查 ( 進入該方法后, 線程池可能關(guān)閉 ), 在進入該方法后, 是否添加了一個線程, 或者線程池是否關(guān)閉. 因此, 我們應(yīng)該再次檢查運行狀態(tài), 如果需要, 將任務(wù)放回隊列中, 或者啟動一個新線程.

  • 如果 不能將任務(wù)入隊, 盡量添加一個新線程. 如果添加失敗, 此時線程池可能關(guān)閉, 或者運行線程數(shù)等于最大線程數(shù), 需要拒絕該任務(wù).

  • public class ThreadPoolExecutor extends AbstractExecutorService {/*** 在將來的某個時間執(zhí)行給定的任務(wù). * 該任務(wù)可能在一個新線程中執(zhí)行, 也可能在當前線程池中已存在的線程中執(zhí)行.* * 如果任務(wù)不能被提交執(zhí)行, 或該線程池失效, 或該線程池線程個數(shù)由于超過最大線程數(shù),* 任務(wù)被 RejectedExecutionHandler 處理. ** @param command 向線程池中提交的任務(wù) * @throws RejectedExecutionException 如果任務(wù)不能被接受, 拋出該異常* @throws NullPointerException 如果任務(wù)為空, 拋出該異常 */public void execute(Runnable command) {if (command == null)throw new NullPointerException();/** 三個步驟:** 1. 如果當前運行線程數(shù)小于核心線程數(shù) , 嘗試啟動新線程執(zhí)行該任務(wù), 該任務(wù)是線程的第一個任務(wù).* 調(diào)用 addWorker 方法會檢查運行狀態(tài), 和線程運行個數(shù), 避免在不應(yīng)該添加線程時執(zhí)行錯誤操作.** 2. 如果任務(wù)成功加入隊列, 需要雙重檢查 ( 進入該方法后, 線程池可能關(guān)閉 ), * 在進入該方法后, 是否添加了一個線程, 或者線程池是否關(guān)閉.* 因此, 我們應(yīng)該再次檢查運行狀態(tài), 如果需要, 將任務(wù)放回隊列中, 或者啟動一個新線程.** 3. 如果不能將任務(wù)入隊, 盡量添加一個新線程. * 如果添加失敗, 此時線程池可能關(guān)閉, 或者運行線程數(shù)等于最大線程數(shù), 需要拒絕該任務(wù).*/int c = ctl.get();// 當前運行的線程數(shù) 小于 核心線程數(shù) if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}// 確保處于運行狀態(tài), 然后將任務(wù)添加到隊列中if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();// 如果不處于運行狀態(tài), 從隊列中移除if (! isRunning(recheck) && remove(command))reject(command); // 拒絕任務(wù)else if (workerCountOf(recheck) == 0)addWorker(null, false);}// 嘗試添加任務(wù) else if (!addWorker(command, false))reject(command);} }

    總結(jié)

    以上是生活随笔為你收集整理的【Android 异步操作】线程池 ( 线程池作用 | 线程池种类 | 线程池工作机制 | 线程池任务调度源码解析 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。