public class Test {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(5));
for(int i=0;i<15;i++){
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("線程池中線程數(shù)目:"+executor.getPoolSize()+"掘宪,隊列中等待執(zhí)行的任務數(shù)目:"+
executor.getQueue().size()+",已執(zhí)行玩別的任務數(shù)目:"+executor.getCompletedTaskCount());
}
executor.shutdown();
}
}
class MyTask implements Runnable {
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
@Override
public void run() {
System.out.println("正在執(zhí)行task "+taskNum);
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task "+taskNum+"執(zhí)行完畢");
}
}
執(zhí)行結果:
正在執(zhí)行task 0
線程池中線程數(shù)目:1歇盼,隊列中等待執(zhí)行的任務數(shù)目:0舔痕,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:2,隊列中等待執(zhí)行的任務數(shù)目:0豹缀,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 1
線程池中線程數(shù)目:3伯复,隊列中等待執(zhí)行的任務數(shù)目:0,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 2
線程池中線程數(shù)目:4邢笙,隊列中等待執(zhí)行的任務數(shù)目:0啸如,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 3
線程池中線程數(shù)目:5,隊列中等待執(zhí)行的任務數(shù)目:0氮惯,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 4
線程池中線程數(shù)目:5叮雳,隊列中等待執(zhí)行的任務數(shù)目:1,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:5妇汗,隊列中等待執(zhí)行的任務數(shù)目:2帘不,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:5,隊列中等待執(zhí)行的任務數(shù)目:3杨箭,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:5厌均,隊列中等待執(zhí)行的任務數(shù)目:4,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:5告唆,隊列中等待執(zhí)行的任務數(shù)目:5棺弊,已執(zhí)行玩別的任務數(shù)目:0
線程池中線程數(shù)目:6,隊列中等待執(zhí)行的任務數(shù)目:5擒悬,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 10
線程池中線程數(shù)目:7模她,隊列中等待執(zhí)行的任務數(shù)目:5,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 11
線程池中線程數(shù)目:8懂牧,隊列中等待執(zhí)行的任務數(shù)目:5侈净,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 12
線程池中線程數(shù)目:9尊勿,隊列中等待執(zhí)行的任務數(shù)目:5,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 13
線程池中線程數(shù)目:10畜侦,隊列中等待執(zhí)行的任務數(shù)目:5元扔,已執(zhí)行玩別的任務數(shù)目:0
正在執(zhí)行task 14
task 3執(zhí)行完畢
task 0執(zhí)行完畢
task 2執(zhí)行完畢
task 1執(zhí)行完畢
正在執(zhí)行task 8
正在執(zhí)行task 7
正在執(zhí)行task 6
正在執(zhí)行task 5
task 4執(zhí)行完畢
task 10執(zhí)行完畢
task 11執(zhí)行完畢
task 13執(zhí)行完畢
task 12執(zhí)行完畢
正在執(zhí)行task 9
task 14執(zhí)行完畢
task 8執(zhí)行完畢
task 5執(zhí)行完畢
task 7執(zhí)行完畢
task 6執(zhí)行完畢
task 9執(zhí)行完畢
從執(zhí)行結果可以看出,當線程池中線程的數(shù)目大于5時旋膳,便將任務放入任務緩存隊列里面澎语,當任務緩存隊列滿了之后,便創(chuàng)建新的線程验懊。如果上面程序中擅羞,將for循環(huán)中改成執(zhí)行20個任務,就會拋出任務拒絕異常了义图。
不過在Java doc中减俏,并不提倡我們直接使用ThreadPoolExecutor,而是使用Executors類中提供的幾個靜態(tài)方法來創(chuàng)建線程池:
Executors.newCachedThreadPool(); //創(chuàng)建一個緩沖池碱工,緩沖池容量大小為Integer.MAX_VALUE
Executors.newSingleThreadExecutor(); //創(chuàng)建容量為1的緩沖池
Executors.newFixedThreadPool(int); //創(chuàng)建固定容量大小的緩沖池
Executors.newScheduledThreadPool(int) //創(chuàng)建一個固定長度的線程池娃承,而且以延遲或定時的方式來執(zhí)行任務
它們實際上也是調(diào)用了ThreadPoolExecutor,只不過參數(shù)都已配置好了怕篷。
newFixedThreadPool創(chuàng)建的線程池corePoolSize和maximumPoolSize值是相等的历筝,它使用的LinkedBlockingQueue;
newSingleThreadExecutor將corePoolSize和maximumPoolSize都設置為1匙头,也使用的LinkedBlockingQueue漫谷;
newCachedThreadPool將corePoolSize設置為0,將maximumPoolSize設置為Integer.MAX_VALUE蹂析,使用的SynchronousQueue舔示,也就是說來了任務就創(chuàng)建線程運行,當線程空閑超過60秒电抚,就銷毀線程惕稻。
實際中,如果Executors提供的四個靜態(tài)方法能滿足要求蝙叛,就盡量使用它提供的四個方法俺祠,因為自己去手動配置ThreadPoolExecutor的參數(shù)有點麻煩,要根據(jù)實際任務的類型和數(shù)量來進行配置借帘。
可以看看線程池--方便的創(chuàng)建和使用:Executors工具類
另外蜘渣,如果ThreadPoolExecutor達不到要求,可以自己繼承ThreadPoolExecutor類進行重寫肺然。