執行緒池ThreadPoolExecutor分析: 執行緒池是什麼時候建立執行緒的,佇列中的任務是什麼時候取出來的?
阿新 • • 發佈:2018-12-15
帶著幾個問題進入原始碼分析:
執行緒池是什麼時候建立執行緒的?
任務runnable task是先放到core到maxThread之間的執行緒,還是先放到佇列?
佇列中的任務是什麼時候取出來的?
什麼時候會觸發reject策略?
core到maxThread之間的執行緒什麼時候會die?
task丟擲異常,執行緒池中這個work thread還能執行其他任務嗎?
至少在new ThreadPoolExecutor()時,Thread物件並沒有初始化. 這裡僅僅指定了幾個初始引數
一段基礎程式碼,進入分析
public static void main(String[] args) { ExecutorService executorService = new ThreadPoolExecutor(2, 5, 0, TimeUnit.DAYS, new ArrayBlockingQueue<>(1), new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); // thread.setDaemon(true); return thread; } }); // 物件建立後,執行緒實際還沒開始建立 // 執行execute時,檢查當前池中執行緒數大小是否小於core number, 如果是,則建立新執行緒 executorService.execute(() -> { System.out.println("[email protected]" + Thread.currentThread().getName()); sleepTime(); System.out.println(1); }); //檢查當前池中執行緒數大小是否小於core number, 如果是,則建立新執行緒 executorService.execute(() -> { System.out.println("[email protected]" + Thread.currentThread().getName()); sleepTime(); System.out.println(2); }); // 檢查當前池中執行緒數大小是否小於core number, 如果不是,則償試放入佇列 // 這個任務是加到佇列去的, 注意佇列大小隻有1, // TODO 佇列中的任務是什麼時候取出來的? executorService.execute(() -> { System.out.println("[email protected]" + Thread.currentThread().getName()); sleepTime(); System.out.println(3); }); // 檢查當前池中執行緒數大小是否小於core number, 如果不是,則償試放入佇列,放入佇列也失敗,則增加新的worker執行緒 // 這個任務是加到core以外的新執行緒去的 executorService.execute(() -> { System.out.println("[email protected]" + Thread.currentThread().getName()); sleepTime(); System.out.println(4); }); }
第3行,建立一個核心池2, 最大池5, 佇列為1的執行緒池
執行第一個execute時,進入除錯jdk原始碼
程式碼塊1
第一個if, 判斷如果當前執行緒數小於corePoolSize, 則建立新的核心worker物件(Worker中指向Thread物件,保持引用,保證不會被GC回收)
我們的示例程式碼中,第1和第2個執行緒都是這樣創建出執行緒的