線程池
- 線程池
- 線程池的實作原理
-
- 飽和政策
- 幾個核心參數
- java中提供的線程池
- execute()和submit()方法
線程池
Java中的線程池是運用場景最多的并發架構,幾乎所有需要異步或并發執行任務的程式都可以使用線程池
什麼是線程池
線程池是一種多線程處理形式,處理過程中将任務添加到隊列,然後在建立線程後自動啟動這些任務。線程池線程都是背景線程。
為什麼要使用線程池
- 降低資源消耗,通過重複利用已建立的線程降低線程建立和銷毀造成的消耗
- 提高響應速度,當任務到達時,任務可以不需要等到線程建立就能立即執行
- 提高線程的可管理性,程是稀缺資源,如果無限制地建立,不僅會消耗系統資源,還會降低系統的穩定性,使用線程池可以進行統一配置設定、調優和監控
線程池的實作原理
線程池是如何處理任務的呢?
1)線程池判斷核心線程池裡的線程是否都在執行任務。如果不是,則建立一個新的工作線程來執行任務。如果核心線程池裡的線程都在執行任務,則進入下個流程。
2)線程池判斷工作隊列是否已經滿。如果工作隊列沒有滿,則将新送出的任務存儲在這個工作隊列裡。如果工作隊列滿了,則進入下個流程。
3)線程池判斷線程池的線程是否都處于工作狀态。如果沒有,則建立一個新的工作線程來執行任務。如果已經滿了,則交給飽和政策來處理這個任務。

如果看不懂,可以看下面這個圖
飽和政策
RejectedExecutionHandler(飽和政策):當隊列和線程池都滿了,說明線程池處于飽和狀态,那麼必須采取一種政策處理送出的新任務。這個政策預設情況下是AbortPolicy,表示無法處理新任務時抛出異常
- AbortPolicy:直接抛出異常。
- CallerRunsPolicy:隻用調用者所線上程來運作任務
- DiscardOldestPolicy:丢棄隊列裡最近的一個任務,并執行目前任務。
- DiscardPolicy:不處理,丢棄掉
幾個核心參數
- corePoolSize corePoolSize(線程池的基本大小):當送出一個任務到線程池時,線程池會建立一個線程來執行任務,即使其他空閑的基本線程能夠執行新任務也會建立線程,等到需要執行的任務數大于線程池基本大小時就不再建立。如果調用了線程池的prestartAllCoreThreads()方法,線程池會提前建立并啟動所有基本線程。
-
runnableTaskQueue (任務隊列):用于儲存等待執行的任務的阻塞隊列。可以選擇以下幾
個阻塞隊列。
-
ArrayBlockingQueue:是一個基于數組結構的有界阻塞隊列,此隊列按FIFO(先進先出)原
則對元素進行排序
-
LinkedBlockingQueue:一個基于連結清單結構的阻塞隊列,此隊列按FIFO排序元素,吞吐量通
常要高于ArrayBlockingQueue。靜态工廠方法Executors.newFixedThreadPool()使用了這個隊列。
-
SynchronousQueue:一個不存儲元素的阻塞隊列。每個插入操作必須等到另一個線程調用
移除操作,否則插入操作一直處于阻塞狀态,吞吐量通常要高于Linked-BlockingQueue,靜态工
廠方法Executors.newCachedThreadPool使用了這個隊列
- ·PriorityBlockingQueue:一個具有優先級的無限阻塞隊列。
-
- keepAliveTime(線程活動保持時間) 線程池的工作線程空閑後,保持存活的時間。是以,如果任務很多,并且每個任務執行的時間比較短,可以調大時間,提高線程的使用率。
- TimeUnit(線程活動保持時間的機關) 可選的機關有天(DAYS)、小時(HOURS)、分鐘(MINUTES)、毫秒(MILLISECONDS)、微秒(MICROSECONDS,千分之一毫秒)和納秒(NANOSECONDS,千分之一微秒)。
java中提供的線程池
Executors類提供了4種不同的線程池:
1、newCachedThreadPool:用來建立一個可以無限擴大的線程池,适用于負載較輕的場景,執行短期異步任務。(可以使得任務快速得到執行,因為任務時間執行短,可以很快結束,也不會造成cpu過度切換)
2、newFixedThreadPool:建立一個固定大小的線程池,因為采用無界的阻塞隊列,是以實際線程數量永遠不會變化,适用于負載較重的場景,對目前線程數量進行限制。(保證線程數可控,不會造成線程過多,導緻系統負載更為嚴重)
3、newSingleThreadExecutor:建立一個單線程的線程池,适用于需要保證順序執行各個任務。
4、newScheduledThreadPool:适用于執行延時或者周期性任務。
execute()和submit()方法
1、execute(),執行一個任務,沒有傳回值。
2、submit(),送出一個線程任務,有傳回值。
前幾天就看完了,一值懶得總結,今天晚上加加班,寫完前幾天複習完的,加油加油!