之前簡單介紹了下BlockingQueue也算是爲本文做了一個前置鋪墊了,今天就來介紹下線程池,因爲如果每個線程任務都要顯示的手動創建的話會大大浪費資源,所以用線程池來統一維護線程的生命週期;下面先介紹瞭解線程池需要提前知道的相關類或接口;
前置類或接口
Executor
線程調度的頂層接口,就定義了一個可以執行線程的execute方法,方法描述如下:void execute(Runnable command);
ExecutorService
Executor的子類之一,定義了線程的一系列生命週期方法;如:
- void shutdown(); 將線程池的狀態設爲SHUTDOWN,表示關閉線程池停止線程池接收新任務,非阻塞式的調用,已經執行的任務會繼續執行
- boolean awaitTermination(long timeout, TimeUnit unit) 阻塞式的shutdown,等所有線程都執行完畢返回
- List
shutdownNow();
將線程池的狀態設置STOP,並試圖停止所有正在執行的任務,將正在等待的任務列表返回;需要注意的是本方法嘗試停止正在執行的線程所用的方法是Thread.interrupt(),而這種方法並不能保證一定能停止線程,所以調用了shutdownNow並不是字面意思一樣馬上退出線程池,有可能也是需要等所有任務都執行完了才退出 - boolean isTerminated(); 如果shutdown後所有的任務都已完成返回true,需要注意的是如果不調用shutdown方法本方法永遠不會返回true
- boolean isShutdown();線程池被關閉返回true
- Future<?> submit(Runnable task);表示提交一個任務並執行,並且有返回值
- void execute(Runnable command); 是其父類Executor的方法,也表示執行一個任務,但是沒有返回值
線程池 ThreadPoolExecutor
快速使用
七個構造參數
- 核心線程數(corePoolSize)
無論是否空閒都會在線程池中活躍的線程數,除非設置了allowCoreThreadTimeOut參數 - 最大線程數(maximumPoolSize)
線程池內允許存在的最大線程數,包括核心線程數 - 允許的空閒時間(keepAliveTime)
線程空閒多久會被回收 - 空閒時間的單位(unit)
線程等待被回收的時間單位 - 任務隊列(workQueue)
BlockingQueue的各種實現,用來接收等待線程池執行的任務 - 線程工廠(threadFactory)
線程Thread的定義工廠,可實現ThreadFactory接口來自定義,也可以使用JDKK自帶的線程工廠 - 拒絕策略(handler)
可以實現RejectedExecutionHandler接口自定義拒絕策略,JDK默認提供四種實現:
-- AbortPolicy 直接拋棄並拋異常(線程池默認拒絕策略)
-- DiscardPolicy 直接拋棄任務不執行也不拋異常
-- DiscardOldestPolicy 拋棄隊列中最老的任務,然後重試execute方法,除非執行器被關閉任務纔會被丟棄。
-- CallerRunsPolicy 由調用execute的線程執行該任務,除非執行器被關閉任務纔會被丟棄。