Java多線程系列——線程池簡介
阿新 • • 發佈:2017-10-29
銷毀 lis trac thread 時間 style rup 結果 del
什麽是線程池?
為了避免系統頻繁地創建和銷毀線程,我們可以讓創建的線程進行復用。
用線程時從線程池中獲取,用完以後不銷毀線程,而是歸還給線程池。
JDK 對線程池的支持
為了更好的控制多線程,JDK 提供了一套線程池框架,結構如下圖所示
它們都在 java.util.concurrent 包中。
- Executor 用來執行任務,它提供了 execute() 方法來執行 Runnable 任務;
- ThreadPoolExecutor 表示一個線程池;
- Executors 它是一個靜態工廠工廠類,通過它可以取得一個擁有特定功能的線程池;
不同特性的線程池
- newFixedThreadPool()
- newSingleThreadPool():返回只有一個線程的線程池。若有多余一個任務被提交,則放入任務隊列中,等待有空閑線程時,按先入先出的順序執行隊列中的任務。
- newCachedThreadPool():返回一個可根據實際情況調整線程數量的線程池。這個方法創建出來的線程池可以被無線擴展,並且當需求降低時會自動收縮。
- newSingleThreadScheduledExecutor():返回一個 ScheduledExecutorService 對象,線程池大小為 1。ScheduledExecutorService 接口在 ExecutorService 接口之上擴展了在給定時間執行某任務的功能,在某個固定時間延遲之後,或周期性執行某個任務。
- newScheduledThreadPool():返回一個 ScheduledExecutorService 對象,並可指定線程數量。
- ScheduledExecutorService 並不一定會立即安排執行任務,而是起到了計劃任務的作用。 它主要有一下三個方法:
- schedule():會在給定的時間,對任務進行一次調度
- scheduleAtFixedRate():創建並執行一個在給定初始延遲後首次啟用的定期操作,後續操作具有給定的周期
- scheduleWithFixedDelay():創建並執行一個在給定初始延遲後首次啟用的定期操作,隨後,在每一次執行終止和下一次執行開始之間都存在給定的延遲
示例
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by zhengbin on 2017/10/24 */ public class ExecutorServiceTest { private static class Task implements Runnable { public void run() { System.out.println(System.currentTimeMillis() + ":Thread ID:" + Thread.currentThread().getId()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { Task t = new Task(); ExecutorService executorService = Executors.newFixedThreadPool(5); for (int i = 0; i < 10;i++) { executorService.execute(t); } executorService.shutdown(); } }
運行結果
1509258535474:Thread ID:11 1509258535474:Thread ID:12 1509258535475:Thread ID:14 1509258535475:Thread ID:15 1509258535475:Thread ID:13 1509258536475:Thread ID:15 1509258536475:Thread ID:11 1509258536475:Thread ID:12 1509258536475:Thread ID:14 1509258536475:Thread ID:13
結果說明
主線程創建了一個固定大小的線程池,線程池的容量是 5。
運行結果輸出了運行的時間戳,可以看到,前 5 個任務執行的時間戳與後 5 個任務的時間戳相差了 1000 毫秒。
這說明在這 10 個任務中,是分成 2 批次執行的。這也完全符合一個只有 5 個線程的線程池的行為。
當把線程池改為 newCachedThreadPool() 時,就會將 10 個任務同時執行。
Java多線程系列——線程池簡介