文章目錄
- 🛸前言
- 🌹Executors的三大方法
- 🍔簡述線程池
- 🎆手動創建線程池
- ?源碼分析
- ?代碼實現,手動創建線程池
- 🎈CallerRunsPolicy()
- 🎈AbortPolicy()
- 🎈DiscardPolicy()
- 🎈DiscardOldestPolicy()

🛸前言
🌹Executors的三大方法
Java 中的 Executors 類提供了創建和管理線程池的工廠方法。主要有以下三種常用的靜態工廠方法:
-
newFixedThreadPool(int nThreads):固定的線程池大小
創建一個固定大小的線程池,其中包含指定數量的線程。如果所有線程都處于活動狀態,并且任務隊列已滿,那么新任務將在任務隊列中等待,直到有空閑的線程可用。
-
newCachedThreadPool():遇強則強,遇弱則弱
創建一個可緩存的線程池,如果線程池的當前規模超過處理需求時,它會回收空閑線程;當需求增加時,則可以添加新的線程,線程池規模不存在限制。
- newSingleThreadExecutor(): 單個線程
創建一個單線程的線程池,該線程池只有一個工作線程,它保證所有任務按順序執行。
這些工廠方法都返回實現了 ExecutorService 接口的 ThreadPoolExecutor 對象,這是 Java 線程池的一個具體實現,提供了對線程池的操作和控制。通過使用這些工廠方法創建線程池,可以方便快捷地滿足不同場景下的線程管理需求。
由于使用Executors不安全,那么我們需要手動創建一個線程池
🍔簡述線程池
線程池是一種用于管理和重用線程的機制,它通過預先創建一組線程,并將任務提交給這些線程來執行。線程池可以有效地控制并發線程的數量,避免了頻繁創建和銷毀線程的開銷,提高了系統的性能和資源利用率。
線程池通常由以下組件構成:
- 線程池管理器(ThreadPoolExecutor):負責創建、管理和調度線程池中的線程。它維護著一個線程池的狀態,包括線程數量、任務隊列、線程工廠等屬性。
- 工作線程(Worker Thread):線程池中的實際執行任務的線程。線程池會創建一定數量的工作線程,每個工作線程可以執行多個任務。
- 任務隊列(Task Queue):用于存儲待執行的任務。當線程池中的線程空閑時,它們會從任務隊列中獲取任務并執行。
- 線程工廠(Thread Factory):用于創建新的線程對象。線程池在需要創建新線程時,會使用線程工廠創建線程對象。
線程池的主要優點包括:
- 提高系統性能:線程池可以控制并發線程的數量,避免了過多的線程競爭和頻繁的線程創建銷毀開銷,提高了系統的性能。
- 提高資源利用率:線程池可以重用線程,避免了線程創建和銷毀的開銷,提高了系統的資源利用率。
- 提供線程管理和監控:線程池提供了對線程的管理和監控機制,可以方便地查看線程池的狀態、線程執行情況等信息,便于調優和排查問題。
使用線程池時,需要根據具體的業務需求和系統資源情況合理配置線程池的大小、任務隊列的容量以及其他相關參數,避免因線程池過小或過大導致的性能問題。
🎆手動創建線程池
?源碼分析
newSingleThreadExecutor的源碼
newFixedThreadPool的源碼
newCachedThreadPool的源碼
其中有個參數長度是Integer,MAX_VALUE,長度過大,可能會堆積大量的請求,對應了上面我們說的不能用Executors,而要用ThreadPoolExecutors
我們發現,上面三者的源碼中都有ThreadPoolExecutor
說明調用線程的本質調用的是ThreadPoolExecutor
下面我們來分析一下ThreadPoolExecutor
下面我們來想象一個場景,來更好的理解線程池
比如我們去銀行辦理業務
銀行有5個窗口,但是只打開了2個(代表核心線程池的大小為2),還有3個沒有開(觸發最大并發量的情況下才會打開這3個窗口),還有容量為3的候客區(阻塞隊列)
然后有用戶去辦理業務了,假如來了3個用戶,2個去窗口了,還有1個在候客區等待,此時,又來了3個用戶,這時候客區的位置不夠了(阻塞隊列滿了),就要打開那關閉的3個窗口(觸發最大并發量了)
?代碼實現,手動創建線程池
🎈CallerRunsPolicy()
package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定義線程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS, //超時等待時間new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());try {for (int i = 1; i <= 10; i++) {//使用線程池后,使用線程池來創建線程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//關閉線程池threadPool.shutdown();}}
}
代碼里面的超時等待時間是什么意思
我們對應上面去銀行的場景,觸發最大并發條件后,所有窗口都打開了,一段時間后,所有用戶都離開了,過了設定的時間都沒有業務,那么后面3個窗口就要關閉
🎈AbortPolicy()
package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定義線程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS, //超時等待時間new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());try {for (int i = 1; i <= 10; i++) {//使用線程池后,使用線程池來創建線程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//關閉線程池threadPool.shutdown();}}
}
🎈DiscardPolicy()
package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定義線程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS, //超時等待時間new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardPolicy());try {for (int i = 1; i <= 10; i++) {//使用線程池后,使用線程池來創建線程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//關閉線程池threadPool.shutdown();}}
}
丟掉任務,但是不會拋出異常
🎈DiscardOldestPolicy()
package org.Test6;import java.util.concurrent.*;public class Demo01 {public static void main(String[] args) {//自定義線程池ExecutorService threadPool = new ThreadPoolExecutor(2,5,3,TimeUnit.SECONDS, //超時等待時間new LinkedBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());try {for (int i = 1; i <= 10; i++) {//使用線程池后,使用線程池來創建線程threadPool.execute(()->{System.out.println(Thread.currentThread().getName()+"ok");});}}catch (Exception e){e.printStackTrace();}finally {//關閉線程池threadPool.shutdown();}}
}
在技術的道路上,我們不斷探索、不斷前行,不斷面對挑戰、不斷突破自我。科技的發展改變著世界,而我們作為技術人員,也在這個過程中書寫著自己的篇章。讓我們攜手并進,共同努力,開創美好的未來!愿我們在科技的征途上不斷奮進,創造出更加美好、更加智能的明天!