一、JAVA線程池使用
在使用Java多線程時引入線程池技術可以大大提高程序性能。Java提供的線程池相關的類主要有四個:Executor、ExecutorService、ScheduledExecutorService和ThreadPoolExecutor。其中,使用ThreadPoolExecutor類可以對線程池進行靈活的設置,可以很好地適應各種場景。
二、JAVA線程池參數設置
在使用Java線程池時,可以根據實際情況對線程池進行參數設置,以達到最佳的程序性能。線程池的主要參數包括以下幾個方面:
1、corePoolSize
核心池大小,即線程池初始化後啟動的線程數量。如果當前線程數量小於核心池大小,則新建線程;否則會將任務放入任務隊列等待執行。
2、maximumPoolSize
最大線程數量,即線程池中最多同時執行的線程數量。當線程池中已有的線程數大於等於corePoolSize時,新任務到來時會將任務放入任務隊列中等待。當任務到來時任務隊列已滿且當前線程數小於maximumPoolSize,則新建線程執行該任務。當線程數已達到最大線程數且任務隊列已滿,則會根據所設置的RejectedExecutionHandler進行相應的拒絕處理。
3、keepAliveTime
線程空閑時間,即空閑線程的存活時間。當線程池中線程數量大於corePoolSize時,需要有一定的機制來回收空閑線程,以便於釋放系統資源。當空閑時間超過keepAliveTime時,空閑線程將被回收。
4、TimeUnit
空閑時間的時間單位。該項參數以TimeUnit枚舉類型傳入,可以設置為TimeUnit.SECONDS、TimeUnit.MINUTES、TimeUnit.HOURS等。
5、workQueue
任務隊列。當線程池中線程數量達到corePoolSize時,新任務到來會被放入任務隊列中。該任務隊列可以是SynchronousQueue、LinkedBlockingQueue、ArrayBlockingQueue等各種線程安全隊列,也可以根據需要自己實現。
6、threadFactory
線程工廠。用於創建新的線程對象。可以通過ThreadFactoryBuilder來創建一個線程工廠。
7、rejectedExecutionHandler
任務拒絕策略。當線程池中線程數量已達到maximumPoolSize並且任務隊列已經滿了時,需要有一種機制來處理新到達的任務。主要有四種處理方式:
- AbortPolicy(默認):直接拋出RejectedExecutionException異常。
- CallerRunsPolicy:任務由調用線程直接執行。
- DiscardOldestPolicy:將等待時間最長的任務從隊列中移除,將新任務加入隊列中。
- DiscardPolicy:直接丟棄該任務。
三、JAVA創建線程池
Java提供了四個線程池類,分別是:
- FixedThreadPool
- CachedThreadPool
- SingleThreadExecutor
- ScheduledThreadPool
1、FixedThreadPool
FixedThreadPool固定大小線程池,會一直新建線程直到線程達到線程池的最大大小,線程池中的線程都是活躍的,線程池中線程數量不會超過給定的數量,並且線程都是在空閑狀態下等待接收任務,所以線程利用率高。
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()); }
2、CachedThreadPool
CachedThreadPool線程池的大小會根據執行的任務數量自動擴展和收縮,沒有核心線程數,超過60秒空閑的線程被終止並從緩衝池中刪除。適用於執行大量短期非同步任務的情景。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue()); }
3、SingleThreadExecutor
SingleThreadExecutor單線程池中只有一個核心線程,該線程會按先進先出的方式執行任務,所以不需要考慮線程同步的問題。適用於需要排隊依次執行任務的情況。
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue())); }
4、ScheduledThreadPool
ScheduledThreadPool定長線程池可以定時或周期性地執行任務。適用於需要執行定時任務的情況。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
完整的Java線程池使用實例:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class ThreadPoolTest { public static void main(String[] args) throws Exception { ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.execute(() -> { System.out.println("任務1開始執行"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任務1執行完畢"); }); executorService.execute(() -> { System.out.println("任務2開始執行"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任務2執行完畢"); }); executorService.execute(() -> { System.out.println("任務3開始執行"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任務3執行完畢"); }); executorService.shutdown(); executorService.awaitTermination(1, TimeUnit.HOURS); } }
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/198629.html