一、什麼是線程池?
線程池是一種線程的集合,線程池中包含了多個線程,這些線程可以輪流執行池中的任務,從而實現線程的復用,提高系統的效率,避免資源的浪費。線程池具有以下特點:
1、線程可以輪流執行,避免創建或銷毀線程的開銷
2、線程數量可以控制,防止系統因為線程過多而崩潰
3、線程池中的線程可以自動重用,不需要每次都重新創建線程
4、線程池可以根據不同的任務進行優先級排序,保證高優先級任務先執行
二、創建線程池的步驟
創建線程池的步驟如下:
1、創建一個線程池對象,設置線程池的屬性,如核心線程數量、最大線程數量、線程空閑時間、等待隊列長度、拒絕策略等等
2、創建一個等待隊列,用於存放等待執行的任務
3、創建一個線程池管理器,用於管理線程池的狀態,比如線程的創建、銷毀、執行任務等
4、向線程池中添加任務,線程池會自動分配線程去執行任務
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyThreadPool { public static void main(String[] args) { //創建線程池 ExecutorService executorService = Executors.newFixedThreadPool(5); //添加任務到線程池 for(int i=0;i<10;i++){ final int task = i; executorService.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行任務:"+task); } }); } //關閉線程池 executorService.shutdown(); } }
三、常見的線程池類型
Java中常見的線程池類型有如下幾種:
1、FixedThreadPool:固定數量線程池,線程數量一旦設定就不會發生變化。
2、CachedThreadPool:緩存線程池,線程數量可以根據任務的多少自動調整。
3、SingleThreadExecutor:單線程線程池,只有一個線程在執行任務,適合於重要的任務需要順序執行的場景。
4、ScheduledThreadPool:定時任務線程池,適用於需要按照一定的周期執行任務的場景。
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class MyScheduledThreadPool { public static void main(String[] args) { //創建定時任務線程池 ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3); //延遲1秒後執行任務 scheduledExecutorService.schedule(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行任務"); } },1, TimeUnit.SECONDS); //每隔2秒執行一次任務 scheduledExecutorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行任務"); } }, 0, 2, TimeUnit.SECONDS); //關閉線程池 scheduledExecutorService.shutdown(); } }
四、線程池的拒絕策略
當線程池中的線程已經全部被佔用,等待隊列已經滿了,此時如果還有新的任務進來,線程池就需要執行拒絕策略。Java中提供了四種線程池的拒絕策略。
1、AbortPolicy:拒絕新任務並拋出異常
2、CallerRunsPolicy:將新任務提交給調用線程來執行
3、DiscardOldestPolicy:將等待隊列中最早的任務丟棄,將新任務添加到等待隊列尾部
4、DiscardPolicy:直接丟棄新任務
import java.util.concurrent.*; public class MyRejectedThreadPool { static class MyTask implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"執行任務"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { //創建線程池,設置拒絕策略為DiscardPolicy ExecutorService executorService = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(1), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy()); //添加任務到線程池 for(int i=0;i<5;i++){ executorService.execute(new MyTask()); } //關閉線程池 executorService.shutdown(); } }
五、線程池的最佳實踐
1、盡量設置合適的線程數量
線程數量過多會導致系統開銷過大,過少會導致系統無法充分利用資源。
2、合理的等待隊列長度
等待隊列長度過長會導致系統處理速度變慢,過短會導致任務不能得到處理。
3、使用合適的拒絕策略
不同的應用場景需要使用不同的拒絕策略。
4、合理的任務劃分與設計
任務應該儘可能合理的拆分,並根據優先級和執行時間進行排序。
六、總結
線程池是一種用於管理線程的機制,具有復用線程、控制線程數量、自動重用、以及優先級等特點,可以提高系統效率,避免資源浪費。在使用線程池時,要注意線程池的屬性設置、拒絕策略的選擇、以及任務的合理劃分與設計,從而達到最佳的效果。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/179903.html