天天看點

android--線程池

使用線程池主要基于這樣的需求,因為建立一個線程因為涉及到與作業系統的互動,是以成本較高。當程式中需要大量而短暫的線程時應考慮使用線程池。

線程池工具類,

package com.chenjun.utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 線程池輔助類,整個應用程式就隻有一個線程池去管理線程。
 * 可以設定核心線程數、最大線程數、額外線程空狀态生存時間,阻塞隊列長度來優化線程池。
 * 下面的資料都是參考Android的AsynTask裡的資料。
 * @author zet
 *
 */
public class ThreadPoolUtils {
    
    private ThreadPoolUtils(){
        
    }
    
    //線程池核心線程數
    private static int CORE_POOL_SIZE = 5;
    
    //線程池最大線程數
    private static int MAX_POOL_SIZE = 100;
    
    //額外線程空狀态生存時間
    private static int KEEP_ALIVE_TIME = 10000;
    
    //阻塞隊列。當核心線程都被占用,且阻塞隊列已滿的情況下,才會開啟額外線程。
    private static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(
            10);
    
    //線程工廠
    private static ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };
    
    //線程池
    private static ThreadPoolExecutor threadPool;
    
    static {
        threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,
                MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, workQueue,
                threadFactory);
    }
    
    
    /**
     * 從線程池中抽取線程,執行指定的Runnable對象
     * @param runnable
     */
    public static void execute(Runnable runnable){
        threadPool.execute(runnable);
    }

}      

使用:

ThreadPoolUtils.execute(new Runnable(){});      

擴充,如果要進行取消操作:

将Runnable對象再進行封裝成FutureTask。

FutureTask<Void> myTask = new FutureTask<Void>(new MyRunnable(), new Void());

ThreadPoolUtils.execute(myTask);

如果需要取消的話,myTask.cancel(true)。

ThreadPoolExecutor類:

1. public ThreadPoolExecutor(int corePoolSize,  
2. int maximumPoolSize,  
3. long keepAliveTime,  
4.                           TimeUnit unit,  
5.                           BlockingQueue<Runnable> workQueue,  
6.                           ThreadFactory threadFactory,  
7.                           RejectedExecutionHandler handler)      

看這個參數很容易讓人以為是線程池裡保持corePoolSize個線程,如果不夠用,就加線程入池直至maximumPoolSize大小,如果還不夠就往workQueue裡加,如果workQueue也不夠就用RejectedExecutionHandler來做拒絕處理。

但實際情況不是這樣,具體流程如下:

1)當池子大小小于corePoolSize就建立線程,并處理請求

2)當池子大小等于corePoolSize,把請求放入workQueue中,池子裡的空閑線程就去從workQueue中取任務并處理

3)當workQueue放不下新入的任務時,建立線程入池,并處理請求,如果池子大小撐到了maximumPoolSize就用RejectedExecutionHandler來做拒絕處理

4)另外,當池子的線程數大于corePoolSize的時候,多餘的線程會等待keepAliveTime長的時間,如果無請求可處理就自行銷毀