Java併發程式設計(6)-ThreadPoolExecutor解讀(1)
文章目錄
更多關於Java併發程式設計的文章請點選這裡:Java併發程式設計實踐(0)-目錄頁
在上文中已經寫過Executor執行緒排程框架的使用及幾種執行緒池,它們是整個Java併發程式設計的核心內容;本文將繼續講解和Executor一樣重要的自定義執行緒池,它能讓我們自己去定義一個多執行緒的執行者擁有的執行緒核心數、最大執行緒數、空閒線存活時間等。
本篇總結自《Java併發程式設計實踐》第八章 應用執行緒池 ,以及相關部落格,想要更加深入瞭解的同學建議閱讀該書。
一、什麼是ThreadPoolExecutor
ThreadPoolExecutor位於java.util.concurrent併發包下,為一些Executor提供了基本的實現,在JDK1.5中由Executors中的工廠中的newCachedThreadPool
二、ThreadPoolExecutor構造方法引數
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,//可不設定
RejectedExecutionHandler handler//可不設定)
- core執行緒還能應付的,則不斷的建立新的執行緒,但不會超出corePoolSize;
- core執行緒無法應付,則將任務扔到佇列裡面,並且用core執行緒去執行;
- 工作佇列滿了(意味著插入任務失敗),則開始建立MAX執行緒,執行緒數達到MAX後,佇列還一直是滿的,則丟擲RejectedExecutionException。
2.1、corePoolSize
核心執行緒池大小,當執行緒池中的執行緒數目小於corePoolSize時,新提交任務將建立一個新執行緒執行任務,即使此時執行緒池中存在空閒執行緒。
2.1、maximumPoolSize
最大執行緒池大小,表示當前池中可以活躍的最大執行緒數目。
2.3、keepAliveTime
執行緒池中超過corePoolSize數目的空閒執行緒最大存活時間。
2.4、TimeUnit
keepAliveTime時間單位。可以設定為TimeUnit.MICROSECONDS
、TimeUnit.SECONDS
等單位,分別表示毫秒和秒。
2.5、workQueue
阻塞任務佇列,用以儲存超出了corePoolSize的執行緒。
2.6、threadFactory
新建執行緒工廠。如果沒有的話則使用系統預設的。
2.7、RejectedExecutionHandler
當提交任務數超過maxmumPoolSize與workQueue之和時,任務會交給RejectedExecutionHandler來處理。如果沒有的話則使用系統預設的。
三、使用自己構造的ThreadPoolExecutor
測試類:
public class ThreadPoolExecutorDemo {
@Test
public void testThreadPoolExecutor(){
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
10,
1000,
TimeUnit.MICROSECONDS,
new ArrayBlockingQueue<Runnable>(3),
new MyThreadFactory(),
new MyRejectedExecutionHandler());
for (int i = 0; i < 35; i++) {
int count = i;
executor.execute(new Runnable() {
@Override
public void run() {
//模擬耗時操作
for (int j = 0; j < 500000; j++) {
//..
}
System.out.println("這是第"+count+"個執行緒在執行任務----"+Thread.currentThread().getName());
}
});
}
}
}
自定義的執行緒工廠類:
public class MyThreadFactory implements ThreadFactory {
//執行緒標識器
private AtomicInteger count = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
//標識器自增1
count.incrementAndGet();
Thread thread = new Thread(r, "自定義執行緒(" + count + ")");
return thread;
}
}
自定義的異常處理類:
public class MyRejectedExecutionHandler implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
//對超出的執行緒任務進行處理
System.out.println("已處理...");
}
}
執行後發現,當迴圈過多時,需要同時活躍的執行緒大於5個之後,新產生的執行緒進入阻塞佇列中,當需要同時活躍的執行緒大於10個之後,新產生的執行緒將被自定義的MyRejectedExecutionHandler 處理。