使用線程池主要基于這樣的需求,因為建立一個線程因為涉及到與作業系統的互動,是以成本較高。當程式中需要大量而短暫的線程時應考慮使用線程池。
線程池工具類,
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長的時間,如果無請求可處理就自行銷毀