android--執行緒池

愛自在發表於2014-12-16

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


執行緒池工具類,轉自 http://www.cnblogs.com/answer1991/archive/2012/04/22/2464524.html

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類:

[java] view plaincopy
  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長的時間,如果無請求可處理就自行銷燬


相關:

http://blog.csdn.net/cutesource/article/details/6061229

http://www.cnblogs.com/answer1991/archive/2012/04/22/2464524.html

相關文章