網頁

2019/6/28

Java Thread Pool 簡介

從Java 1.5開始,增加了java.util.concurrent的Concurrency API來處理併行程式,java.util.concurrent提供多個類別及方法讓我們能夠更方便地建立,管理,執行多執行緒,其中一個重要的特色就是Thread Pool。

在以前建立多執行緒時,都是用Thread產生新的執行緒,然後呼叫Thread.start()來執行任務(Runnable),但建立新執行緒的成本很高,因為Java建立執行緒時,JVM就要分配一塊stack區塊給執行緒,向作業系統註冊這條執行緒,建立thread descriptors等,這些動作為建立新執行緒的overhead(固定開銷);而執行緒完成任務後就直接關閉,下一次要用到多執行緒時又是重新建一個,很耗費系統資源,如果程式中經常用到多執行緒,會對效能造成負面影響。


Thread Pool是個執行緒池,原理類似資料庫連接池Connection Pool。Thread Pool中通常有多個數量固定的執行緒,每當有任務要執行時,就使用Thread Pool的執行緒來處理,任務完成後該執行緒不會關閉,而是繼續等待下個任務。Thread Pool中的執行緒又稱為Worker Thread。

如果任務數量超過Thread Pool中的執行緒數量,則多出的任務會先被放在任務隊列(BlockingQueue)中等待,直到Thread Pool的執行緒有空閒時,才會去隊列中取出未完成的任務來執行。


Thread pool

java.util.concurrent中對Thread Pool的實作類別之一為ThreadPoolExecutor

節錄部分Java 8 ThreadPoolExecutor的原始碼如下,可以看到如上所述的幾個重要特色,如任務隊列,Worker Threads等。

ThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService {
    ...
    private final BlockingQueue<Runnable> workQueue; // 任務隊列
    ...
    private final HashSet<Worker> workers = new HashSet<Worker>(); // Worker Threads的Pool
    
    ...
    
    // Worker Thread為ThreadPoolExecutor的內部類別
    private final class Worker
        extends AbstractQueuedSynchronizer
        implements Runnable
    {
        ....
    }
    ...
}

不過在撰寫程式時通常不會直接呼叫ThreadPoolExecutor的建構式,而是透過java.util.concurrent中的工廠類別Executors的靜態方法來取得ThreadPoolExecutor的抽像介面ExecutorService對執行緒進行操作。簡單的用法請參考Java 使用ExecutorService來執行多執行緒


參考:

沒有留言:

張貼留言