從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來執行多執行緒。
參考:
沒有留言:
張貼留言