更新時(shí)間:2023-04-13 來(lái)源:黑馬程序員 瀏覽量:
Java中創(chuàng)建線程池時(shí),有以下幾個(gè)核心構(gòu)造參數(shù):
線程池中的核心線程數(shù)量,即在沒(méi)有任務(wù)需要執(zhí)行時(shí)線程池的基本大小。
線程池中允許的最大線程數(shù)量。
當(dāng)線程池中的線程數(shù)量大于核心線程數(shù)量時(shí),多余的空閑線程在等待新任務(wù)到來(lái)時(shí)能夠存活的最長(zhǎng)時(shí)間。
keepAliveTime 參數(shù)的時(shí)間單位。
用于存放待執(zhí)行任務(wù)的阻塞隊(duì)列。
用于創(chuàng)建新線程的工廠類(lèi)。
當(dāng)線程池中的線程數(shù)量達(dá)到最大線程數(shù)量并且隊(duì)列已滿時(shí)的飽和策略,常見(jiàn)的策略有拋出異常、丟棄任務(wù)、丟棄隊(duì)列中最老的任務(wù)、直接在調(diào)用者線程中執(zhí)行等。
下面是一個(gè)基本的線程池創(chuàng)建和使用的代碼演示:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolDemo { public static void main(String[] args) { // 創(chuàng)建一個(gè)具有固定線程數(shù)的線程池 ExecutorService executor = Executors.newFixedThreadPool(2); // 提交任務(wù)到線程池中 for (int i = 1; i <= 10; i++) { executor.submit(new Task(i)); } // 關(guān)閉線程池 executor.shutdown(); } } class Task implements Runnable { private int taskId; public Task(int taskId) { this.taskId = taskId; } @Override public void run() { System.out.println("Task #" + taskId + " is running."); } }
這個(gè)例子中,創(chuàng)建了一個(gè)具有固定線程數(shù)(2個(gè))的線程池,并提交了10個(gè)任務(wù)到線程池中執(zhí)行。每個(gè)任務(wù)是一個(gè)簡(jiǎn)單的Runnable對(duì)象,只是打印了一行文本。在執(zhí)行完所有任務(wù)后,線程池會(huì)自動(dòng)關(guān)閉。
如果需要指定線程池的其他構(gòu)造參數(shù),可以使用ThreadPoolExecutor類(lèi)來(lái)創(chuàng)建線程池。接下來(lái)我們用一段代碼,來(lái)演示如何使用ThreadPoolExecutor類(lèi)創(chuàng)建一個(gè)具有4個(gè)核心線程、最大線程數(shù)為8、空閑線程存活時(shí)間為30秒、任務(wù)隊(duì)列大小為20的線程池。
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPoolDemo { public static void main(String[] args) { int corePoolSize = 4; int maximumPoolSize = 8; long keepAliveTime = 30; TimeUnit unit = TimeUnit.SECONDS; ArrayBlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(20); ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); // 提交任務(wù)到線程池中 for (int i = 1; i <= 20; i++) { executor.submit(new Task(i)); } // 關(guān)閉線程池 executor.shutdown(); } } class Task implements Runnable { private int taskId; public Task(int taskId) { this.taskId = taskId; } @Override public void run() { System.out.println("Task #" + taskId + " is running."); } }
在這個(gè)例子中,首先定義了線程池的各個(gè)構(gòu)造參數(shù),然后使用ThreadPoolExecutor類(lèi)創(chuàng)建了一個(gè)具有指定參數(shù)的線程池。這個(gè)例子中,任務(wù)隊(duì)列使用了一個(gè)ArrayBlockingQueue,它可以存儲(chǔ)20個(gè)任務(wù)。在執(zhí)行完所有任務(wù)后,線程池會(huì)自動(dòng)關(guān)閉。
除了使用ThreadPoolExecutor類(lèi),還可以使用Executors類(lèi)的其他靜態(tài)工廠方法來(lái)創(chuàng)建不同類(lèi)型的線程池:
1.創(chuàng)建一個(gè)具有單個(gè)線程的線程池,適用于需要按順序執(zhí)行任務(wù)的情況。
ExecutorService executor = Executors.newSingleThreadExecutor();
2.創(chuàng)建一個(gè)具有固定線程數(shù)的線程池,適用于需要保證線程數(shù)量固定的情況。
ExecutorService executor = Executors.newFixedThreadPool(4);
3.創(chuàng)建一個(gè)具有緩存的線程池,適用于需要執(zhí)行大量短期異步任務(wù)的情況。這個(gè)線程池會(huì)根據(jù)任務(wù)的數(shù)量動(dòng)態(tài)調(diào)整線程數(shù)量,如果線程池中的線程閑置時(shí)間超過(guò)60秒,這些線程就會(huì)被終止并從線程池中移除。
ExecutorService executor = Executors.newCachedThreadPool();
4.創(chuàng)建一個(gè)具有調(diào)度功能的線程池,適用于需要按一定間隔執(zhí)行任務(wù)的情況。這個(gè)線程池會(huì)在指定的延遲后,周期性地執(zhí)行任務(wù)。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); executor.scheduleAtFixedRate(new Task(), 0, 1, TimeUnit.SECONDS);
在這個(gè)例子中,創(chuàng)建了一個(gè)具有兩個(gè)線程的ScheduledExecutorService,然后使用scheduleAtFixedRate方法來(lái)周期性地執(zhí)行任務(wù)。這個(gè)方法的參數(shù)說(shuō)明:第一個(gè)參數(shù)是要執(zhí)行的任務(wù),第二個(gè)參數(shù)是任務(wù)的初始延遲時(shí)間,第三個(gè)參數(shù)是任務(wù)的執(zhí)行周期,第四個(gè)參數(shù)是時(shí)間單位。
總的來(lái)說(shuō),Java中的線程池提供了一種高效管理線程的方式,能夠避免頻繁創(chuàng)建和銷(xiāo)毀線程,提高程序的性能和穩(wěn)定性。在使用線程池時(shí),需要根據(jù)實(shí)際情況選擇不同類(lèi)型的線程池和合適的構(gòu)造參數(shù)。