直接上代碼了
package cn.gaialine.threadpool;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.TimeUnit;
/**
* 線程池測試用例
* @author yangyong
*
*/
public class TestThreadPool {
//線程池維護線程的最少數量
private static final int COREPOOLSIZE = 2;
//線程池維護線程的最大數量
private static final int MAXINUMPOOLSIZE = 5;
//線程池維護線程所允許的空閒時間
private static final long KEEPALIVETIME = 4;
//線程池維護線程所允許的空閒時間的單位
private static final TimeUnit UNIT = TimeUnit.SECONDS;
//線程池所使用的緩衝隊列,這裏隊列大小爲3
private static final BlockingQueue<Runnable> WORKQUEUE = new ArrayBlockingQueue<Runnable>(3);
//線程池對拒絕任務的處理策略:AbortPolicy爲拋出異常;CallerRunsPolicy爲重試添加當前的任務,他會自動重複調用execute()方法;DiscardOldestPolicy爲拋棄舊的任務,DiscardPolicy爲拋棄當前的任務
private static final AbortPolicy HANDLER = new ThreadPoolExecutor.AbortPolicy();
public static void main(String[] args) {
// TODO 初始化線程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(COREPOOLSIZE, MAXINUMPOOLSIZE, KEEPALIVETIME, UNIT, WORKQUEUE, HANDLER);
for (int i = 1; i < 11; i++) {
String task = "task@"+i;
System.out.println("put->"+task);
//一個任務通過 execute(Runnable)方法被添加到線程池,任務就是一個 Runnable類型的對象,任務的執行方法就是 Runnable類型對象的run()方法
//處理任務的優先級爲:核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務
//設此時線程池中的數量爲currentPoolSize,若currentPoolSize>corePoolSize,則創建新的線程執行被添加的任務,
//當corePoolSize+workQueue>currentPoolSize>=corePoolSize,新增任務被放入緩衝隊列,
//當maximumPoolSize>currentPoolSize>=corePoolSize+workQueue,建新線程來處理被添加的任務,
//當currentPoolSize>=maximumPoolSize,通過 handler所指定的策略來處理新添加的任務
//本例中可以同時可以被處理的任務最多爲maximumPoolSize+WORKQUEUE=8個,其中最多5個在線程中正在處理,3個在緩衝隊列中等待被處理
//當currentPoolSize>corePoolSize時,如果某線程空閒時間超過keepAliveTime,線程將被終止。這樣,線程池可以動態的調整池中的線程數
threadPool.execute(new ThreadPoolTask(task));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
threadPool.shutdown();//關閉主線程,但線程池會繼續運行,直到所有任務執行完纔會停止。若不調用該方法線程池會一直保持下去,以便隨時添加新的任務
}
}
package cn.gaialine.threadpool;
import java.io.Serializable;
/**
* 任務task
* @author yangyong
*
*/
public class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = -8568367025140842876L;
private Object threadPoolTaskData;
private static int produceTaskSleepTime = 10000;
public ThreadPoolTask(Object threadPoolTaskData) {
super();
this.threadPoolTaskData = threadPoolTaskData;
}
public void run() {
// TODO Auto-generated method stub
System.out.println("start..."+threadPoolTaskData);
try {
//模擬線程正在執行任務
Thread.sleep(produceTaskSleepTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("stop..."+threadPoolTaskData);
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
執行測試,每1秒添加一個任務,每個任務執行10秒,查看打印數據
put->task@1
start...task@1
put->task@2
start...task@2
put->task@3
put->task@4
put->task@5
put->task@6
start...task@6
put->task@7
start...task@7
put->task@8
start...task@8
put->task@9
Exception in thread "main" java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.reject(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.execute(Unknown Source)
at cn.gaialine.threadpool.TestThreadPool.main(TestThreadPool.java:42)
stop...task@1
start...task@3
stop...task@2
start...task@4
stop...task@6
start...task@5
stop...task@7
stop...task@8
stop...task@3
stop...task@4
stop...task@5
從中可以看出task1和task2依次最先執行,這時候currentPoolSize=2達到了corePoolSize,task3、task4、task5被送入緩衝隊列,達到了workQueue最大值3,task6、task7、task8開啓新的線程開始執行,此時currentPoolSize=5達到了maximumPoolSize,task9、task10根據AbortPolicy策略拋出異常,不再執行task9和task10。10秒鐘後task1、task2....依次執行完畢釋放線程,開始執行隊列裏的task3、task4、task5,最後task3、4、5執行完畢,所有任務完成
// 固定工作線程數量的線程池
ExecutorService executorService1 = Executors.newFixedThreadPool(3);
// 一個可緩存的線程池
ExecutorService executorService2 = Executors.newCachedThreadPool();
// 單線程化的Executor
ExecutorService executorService3 = Executors.newSingleThreadExecutor();
// 支持定時的以及週期性的任務執行
ExecutorService executorService4 = Executors.newScheduledThreadPool(3);