之前幾天在啟動執行緒的方式都是直接 new Thread() 之後再去呼叫 start 方法,使用這種方法啟動執行緒較沒有彈性而且管理上也比較不方便。Java 內建有提供 Executors 和 ExecutorService 類別,可以方便開發者管理執行緒。它可以建立執行緒的 Pool 讓我們可以重覆的使用執行緒有效的控制 CPU 資源,另外也可以使用 Sheduler 管理執行緒的排程。因此學會使用 Executors 和 ExecutorService 可以幫助我們方便快速開發多執行緒的程式。
Executors 提供了 newCacheThreadPool、newFixThreadPool、newSingleThreadExecutor、newScheduledThreadPool、newSingleThreadScheduledExecutor…等等的方法來建立執行緒 Pool。每個方法的說明如下:
newCacheThreadPool:執行緒 Pool 發現有執行緒執行完之後,會將資源回收重新的再使用。如果沒有回收的資源,那就會再去建立執行緒。
newFixThreadPool:執行緒 Pool 只會有固定數量的執行緒再執行,如果啟動的數量超過 pool 的數量那執行緒就會被放入 Queue 等待被執行。
newSingleThreadExecutor:執行緒 pool 只會有一個執行緒可以執行
newScheduledThreadPool:執行緒 pool 會按照排程去執行執行緒
newSingleThreadScheduledExecutor:執行緒 pool 只會有一個執行緒可以按照 scheduler 的排程去執行
今天先寫 newCacheThreadPool 的 sample code 如下程式。其它的方法留到明天和後天來介紹
public class ThreadExample implements Runnable {
@Override
public void run() {
String threadName= Thread.currentThread().getName();
System.out.println("run " + threadName + " thread");
}
}
以上的程式主要是會印出目前執行到的執行緒名稱,確認目前是哪一個執行緒被執行到
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String args[]) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
try {
for (int i = 0; i < 5; i++) {
//Thread.sleep(1000);
cachedThreadPool.execute(new ThreadExample());
}
} catch(Exception e){
throw new RuntimeException(e);
} finally {
cachedThreadPool.shutdown();
}
}
}
上面的主程式,主要使用 Executors 的 newCachedThreadPool 方法建立執行緒 Pool 會得到 ThredPoolExecutor 的實作,這裡可以使用 ExecutorService interface 的原因是 ThreadPoolExecutor 是繼承 AbstractExecutorService,AbstractExecutorService 又會實作 ExecutorService interface,因此 newCachedThreadPool 方法可以給 ExecutorService 型態使用。
之後就會使用迴圈執行 5 次 thread,程式執行完畢之後要把 cachedThreadPool shutdown,不然程式不會結束。
執行的結果如下:
run pool-1-thread-1 thread
run pool-1-thread-2 thread
run pool-1-thread-1 thread
run pool-1-thread-3 thread
run pool-1-thread-2 thread
如果把上面的主程式的 Thread.sleep(1000) 註解拿掉可以看到,程式執行結果如下:
run pool-1-thread-1 thread
run pool-1-thread-1 thread
run pool-1-thread-1 thread
run pool-1-thread-1 thread
run pool-1-thread-1 thread
每隔一秒再執行執行緒的話,因為執行緒執行完之後就會換其它執行緒的物件使用。所以每一次的執行緒執行都會使用 pool-1-thread-1 的執行緒執行,這也就是使用 Executors 的好處可以有效控制執行緒的數量。
明天還會繼續介紹 newFixThreadPool、newSingleThreadExecutor 方法的使用。