Android中的線程池理解

Android中的線程池

一、線程池的作用:

(1)避免線程重複創建和銷燬造成性能浪費
(2)控制線程最大併發數,避免大量線程之間相互搶佔資源造成阻塞
(3)便於對線程進行簡單的管理

二、ThreadPoolExecutor

Android的線程池來源於java的Executor(接口),其具體實現爲ThreadPoolExecutor。
接下來爲ThreadPoolExecutor,其構造方法爲:

     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                   TimeUnit unit,
                                   BlockingQueue<Runnable> workQueue,
                                   ThreadFactory threadFactory)

接下來介紹這上面各個參數的具體含義:
corePoolSize:核心線程數,啥爲核心線程數?一般情況下,核心線程在線程池中都是一直存活的,即使它們處於閒置狀態,除非設置ThreadPoolExecutor的allowCoreThreadTime這個屬性爲true,那麼當閒置時間超過keepAliveTime時,核心線程就會停止。

maximunPoolSize:這個是線程池中的最大線程數,當活動線程達到這個數目時,到來的任務就會被阻塞

keepAliveTime:非核心線程閒置的超時時長,超過這個時間,非核心線程就會被回收。

unit:keepAliveTime的時間單位。

workQueue:任務隊列,通過線程池的execute提交的Runnable對象會存儲到這個參數中。

threadFactory(接口):爲線程池提供創建新線程的功能,裏面唯一的方法:Thread newThread(Runnable r)。

接下來參考下AsyncTask中對ThreadPoolExecutor的配置:

 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
 private static final int KEEP_ALIVE = 1;
 private static final ThreadFactory sThreadFactory = new ThreadFactory() {
 private final AtomicInteger mCount = new AtomicInteger(1);
 public Thread newThread(Runnable r) {
 	return new Thread(r,"AsyncTask #" + mCount.getAndIncrement());
 }
 };
 private static final BlockingQueue<Runnable> sPoolWorkQueue =
 							new LinkedBlockingQueue<Runnable>(128);

 public static final Executor THREAD_POOL_EXECUTOR
 = new ThreadPoolExecutor(CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE,sThreadFactory

從上代碼可知:
(1)核心線程數爲CPU核心數減1,再和4比較取值;
原因:防止後臺任務將CPU資源完全耗盡,減掉這個1是留給主線程使用的。正常來說核心線程數應設置爲CPU核心數+1,其原因是:提高CPU的利用率。
我們需要根據任務是計算密集型(指處理這種任務時,線程不會發生阻塞,線程不阻塞就一定程度代表 CPU 一直在忙碌)或者是IO密集型(指運行該類任務時線程多會發生阻塞,一旦阻塞,CPU 就多被閒置)來設置線程池的大小。
對於計算密集型的任務,在有N 個處理器的系統上,當線程池的大小爲 N+1 時,能實現 CPU 的最優利用率。
(2)線程池最大的線程數爲CPU核心數的2N+1;(IO密集型)
(3)核心線程無超時機制,非核心線程在閒置時的超時時間爲1秒;
(4)任務隊列的容量爲128;

三、線程池的分類

主要有四類:FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor
(1)FixedThreadPool,通過Executors的newFixedThreadPool方法來創建

 public static ExecutorService newFixedThreadPool(int nThreads) {
 return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONDS,
 									new LinkedBlockingQueue<Runnable>());
 }

特點·裏面只有核心線程,線程數量固定。線程處於空閒狀態時,並不會被回收。所有線程都處於活動狀態的時候,新任務都會處於等待狀態。

(2)CachedThreadPool,通過Executors的newCachedThreadPool方法來創建。

    public static ExecutorService newCachedThreadPool() {
    	return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<Runnable>());
    }

特點:裏面只有非核心線程,其最大線程數可以任意大。超時機制爲60S,超過這個數,線程池中的線程都會被超時停止,這個時候CachedThreadPool爲空。適合執行大量耗時比較少的任務。

(3)ScheduledThreadPool,通過Executors的newScheduledThreadPool方法來創建。

    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize,Integer.MAX_VALUE,0,NANOSECONDS,
        new DelayedWorkQueue());
    }

特點:核心線程數固定,非核心線程無限制,非核心線程一閒置馬上會被回收。

(4)SingleThreadExecutor,通過Executors的newSingleThreadExecutor方法來創建。

    public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));
    }

特點:所有任務都在同一個線程中按順序執行。

參考自《Android開發藝術探索》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章