ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 線程池維護線程的最少數量
maximumPoolSize:線程池維護線程的最大數量
keepAliveTime: 線程池維護線程所允許的空閒時間
unit: 線程池維護線程所允許的空閒時間的單位
workQueue: 線程池所使用的緩衝隊列
handler: 線程池對拒絕任務的處理策略
public class TestFutureTask {
/**
* @param args
* @create_time 2011-6-24 下午03:41:57
*/
public static void main(String[] args) {
//創建線程池
ThreadPoolExecutor pool=new ThreadPoolExecutor(3,3,2,TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10),new ThreadPoolExecutor.AbortPolicy());
List<FutureTask<String>> tasks=new ArrayList<FutureTask<String>>();
for(int i=0;i<10;i++){
FutureTask<String> futureTask=new FutureTask<String>(new ThreadPoolTask(i));
pool.submit(futureTask);
tasks.add(futureTask);
}
for (FutureTask<String> futureTask : tasks) {
try {
//阻塞一直等待執行完成拿到結果
System.out.println("future result:"+futureTask.get());
//阻塞一直等待執行完成拿到結果,如果在超時時間內,沒有拿到則拋出異常
// System.out.println("future result:"+futureTask.get(1,TimeUnit.SECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} //捕獲超時異常
// catch (TimeoutException e) {
// e.printStackTrace();
// }
}
}
/**
* 執行業務計算
*
* @date 2011-6-24
* Copyright (C) 2010-2012 www.2caipiao.com Inc. All rights reserved.
*/
public static class ThreadPoolTask implements Callable<String>{
private int value;
public ThreadPoolTask(int value){
this.value=value;
}
@Override
public String call() throws Exception {
//計算
System.out.println("value-----"+value++);
Thread.sleep(2000);
return String.valueOf(value);
}
}
}
當一個任務通過execute(Runnable)方法欲添加到線程池時:
如果此時線程池中的數量小於corePoolSize,即使線程池中的線程都處於空閒狀態,也要創建新的線程來處理被添加的任務。
如果此時線程池中的數量等於 corePoolSize,但是緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列。
如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。
如果此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,並且線程池中的數量等於maximumPoolSize,那麼通過 handler所指定的策略來處理此任務。也就是:處理任務的優先級爲:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
當線程池中的線程數量大於 corePoolSize時,如果某線程空閒時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數。
unit可選的參數爲java.util.concurrent.TimeUnit中的幾個靜態屬性:
NANOSECONDS、
MICROSECONDS、
MILLISECONDS、
SECONDS。
workQueue常用的是:java.util.concurrent.ArrayBlockingQueue
handler有四個選擇:
ThreadPoolExecutor.AbortPolicy()
拋出java.util.concurrent.RejectedExecutionException異常
ThreadPoolExecutor.CallerRunsPolicy()
重試添加當前的任務,他會自動重複調用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
拋棄舊的任務
ThreadPoolExecutor.DiscardPolicy()
拋棄當前的任務
本例介紹一個特殊的隊列:BlockingQueue,如果BlockingQueue是空的,從BlockingQueue取東西的操作將會被阻斷進入等待狀態,直到BlockingQueue進了東西纔會被喚醒,同樣,如果BlockingQueue是滿的,任何試圖往裏存東西的操作也會被阻斷進入等待狀態,直到BlockingQueue裏有空間時纔會被喚醒繼續操作。
本例再次實現前面介紹的籃子程序,不過這個籃子中最多能放得蘋果數不是1,可以隨意指定。當籃子滿時,生產者進入等待狀態,當籃子空時,消費者等待。
BlockingQueue定義的常用方法如下:
add(anObject):把anObject加到BlockingQueue裏,如果BlockingQueue可以容納,則返回true,否則拋出異常。
offer(anObject):表示如果可能的話,將anObject加到BlockingQueue裏,即如果BlockingQueue可以容納,則返回true,否則返回false。
put(anObject):把anObject加到BlockingQueue裏,如果BlockingQueue沒有空間,則調用此方法的線程被阻斷直到BlockingQueue裏有空間再繼續。
poll(time):取走BlockingQueue裏排在首位的對象,若不能立即取出,則可以等time參數規定的時間,取不到時返回null。
take():取走BlockingQueue裏排在首位的對象,若BlockingQueue爲空,阻斷進入等待狀態直到BlockingQueue有新的對象被加入爲止。
BlockingQueue有四個具體的實現類,根據不同需求,選擇不同的實現類:
ArrayBlockingQueue:規定大小的BlockingQueue,其構造函數必須帶一個int參數來指明其大小。其所含的對象是以FIFO(先入先出)順序排序的。
LinkedBlockingQueue:大小不定的BlockingQueue,若其構造函數帶一個規定大小的參數,生成的BlockingQueue有大小限制,若不帶大小參數,所生成的BlockingQueue的大小由Integer.MAX_VALUE來決定。其所含的對象是以FIFO順序排序的。
PriorityBlockingQueue:類似於LinkedBlockingQueue,但其所含對象的排序不是FIFO,而是依據對象的自然排序順序或者是構造函數所帶的Comparator決定的順序。
SynchronousQueue:特殊的BlockingQueue,對其的操作必須是放和取交替完成的。
public class BlockingQueueTest {
/** *//**
* 定義裝蘋果的籃子
*/
public static class Basket{
// 籃子,能夠容納3個蘋果
BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);
// 生產蘋果,放入籃子
public void produce() throws InterruptedException{
// put方法放入一個蘋果,若basket滿了,等到basket有位置
basket.put("An apple");
}
// 消費蘋果,從籃子中取走
public String consume() throws InterruptedException{
// get方法取出一個蘋果,若basket爲空,等到basket有蘋果爲止
return basket.take();
}
}
// 測試方法
public static void testBasket() {
// 建立一個裝蘋果的籃子
final Basket basket = new Basket();
// 定義蘋果生產者
class Producer implements Runnable {
public void run() {
try {
while (true) {
// 生產蘋果
System.out.println("生產者準備生產蘋果:"
+ System.currentTimeMillis());
basket.produce();
System.out.println("生產者生產蘋果完畢:"
+ System.currentTimeMillis());
// 休眠300ms
Thread.sleep(300);
}
} catch (InterruptedException ex) {
}
}
}
// 定義蘋果消費者
class Consumer implements Runnable {
public void run() {
try {
while (true) {
// 消費蘋果
System.out.println("消費者準備消費蘋果:"
+ System.currentTimeMillis());
basket.consume();
System.out.println("消費者消費蘋果完畢:"
+ System.currentTimeMillis());
// 休眠1000ms
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
}
}
}
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer();
Consumer consumer = new Consumer();
service.submit(producer);
service.submit(consumer);
// 程序運行5s後,所有任務停止
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
service.shutdownNow();
}
public static void main(String[] args) {
BlockingQueueTest.testBasket();
}
}
http://apps.hi.baidu.com/share/detail/23487327 http://yaozhiqiang109.iteye.com/blog/1104232