iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 18
0
Software Development

30 天介紹 Java 的 Thread系列 第 18

Day 18 使用 Executors 和 ExecutorService 啟動執行緒 (一)

  • 分享至 

  • xImage
  •  

之前幾天在啟動執行緒的方式都是直接 new Thread() 之後再去呼叫 start 方法,使用這種方法啟動執行緒較沒有彈性而且管理上也比較不方便。Java 內建有提供 Executors 和 ExecutorService 類別,可以方便開發者管理執行緒。它可以建立執行緒的 Pool 讓我們可以重覆的使用執行緒有效的控制 CPU 資源,另外也可以使用 Sheduler 管理執行緒的排程。因此學會使用 Executors 和 ExecutorService 可以幫助我們方便快速開發多執行緒的程式。

Executors 提供了 newCacheThreadPool、newFixThreadPool、newSingleThreadExecutor、newScheduledThreadPool、newSingleThreadScheduledExecutor…等等的方法來建立執行緒 Pool。每個方法的說明如下:

  1. newCacheThreadPool:執行緒 Pool 發現有執行緒執行完之後,會將資源回收重新的再使用。如果沒有回收的資源,那就會再去建立執行緒。

  2. newFixThreadPool:執行緒 Pool 只會有固定數量的執行緒再執行,如果啟動的數量超過 pool 的數量那執行緒就會被放入 Queue 等待被執行。

  3. newSingleThreadExecutor:執行緒 pool 只會有一個執行緒可以執行

  4. newScheduledThreadPool:執行緒 pool 會按照排程去執行執行緒

  5. 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 方法的使用。


上一篇
Day 17 使用 ThreadFactory 建立執行緒
下一篇
Day 19 使用 Executors 和 ExecutorService 啟動執行緒 (二)
系列文
30 天介紹 Java 的 Thread30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言