java執行緒池之一:建立執行緒池的方法
在Java開發過程中經常需要用到執行緒,為了減少資源的開銷,提高系統性能,Java提供了執行緒池,即事先建立好執行緒,如果需要使用從池中取即可,Java中建立執行緒池有以下的方式,
1、使用ThreadPoolExecutor類
2、使用Executors類
其實這兩種方式在本質上是一種方式,都是通過ThreadPoolExecutor類的方式,下面分析其使用方式。
一、ThreadPoolExecutor的方式
1、使用方法
檢視JDK的原始碼,ThreadPoolExecutor類提供了以下構造方法,
可以看到有四個構造方法,先看第一個構造方法,其程式碼如下,
public ThreadPoolExecutor(intcorePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
從上面的程式碼中可以確定,我們需要傳的引數有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue
下面對這幾個引數進行說明
corePoolSize:執行緒池的核心執行緒數;
maximumPoolSize:執行緒池的最大執行緒數;
keepAliveTime:執行緒池空閒時執行緒的存活時長;
unit:執行緒存活時長大單位,結合上個引數使用;
workQueue:存放任務的佇列,使用的是阻塞佇列;
在這個方法中呼叫了另外的一個構造方法,即上圖中四個構造方法中的第四個,從原始碼中得知,一個執行緒池包含的屬性共有corePoolSize、maximumPoolSize、keepAliveTime、unit、workQueue、threadFactory、handler七個,上面說到了五個,下面是其他兩個的含義,
threadFactory:執行緒池建立執行緒的工廠;
handler:在佇列(workQueue)和執行緒池達到最大執行緒數(maximumPoolSize)均滿時仍有任務的情況下的處理方式;
上面的七個引數,也即ThreadPoolExecutor的第四個構造方法需要的引數。
我們再來看中間的兩個構造方法,和第一個的區別在於,第二個和第三個指定了建立執行緒的工廠和執行緒池滿時的處理策略。
通過上面的方式便建立了執行緒池
二、Executors的方式
1、使用方法
Executors類提供了下面的構造方法,
可以看到提供了約10個的構造方法,但是發現其方法返回值為ExecutorService,這不是我們要的ThreadPoolExecutor那,別急,看下ExecutorService這個類是什麼,
其原始碼如下,
其是一個介面,和ThreadPoolExecutor沒什麼關係那,不對,可以大膽猜想下,ThreaPoolExecutor可以實現介面,驗證下我們的猜想,
ThreadPoolExecutor繼承了AbstractExecutorService
AbstractExecutorService抽象類實現了ExecutorService介面,那麼ThreadPoolExcutor和ExecutorService就有了關係。
我們再挑選ExecutorService中的方法看下其具體實現,
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
從上面的程式碼中可以看出,其返回的是ThreaPoolExecutor物件,呼叫的是ThreaPoolExecutor類四個構造方法中的第一個。
總結,上面兩種建立執行緒池的方式,其本質都是通過ThreaPoolExecutor類的構造方法的方式,所以ThreaPoolExecutor是重點。