縣政府網(wǎng)站建設(shè)方案比百度強(qiáng)大的搜索引擎
1、使用Executors工廠方法:
使用Executors工廠方法創(chuàng)建線程池是一種簡(jiǎn)單快捷的方式,適用于一些常見的線程池需求。以下是幾個(gè)示例,演示如何使用Executors工廠方法創(chuàng)建不同類型的線程池:
固定大小線程池 (newFixedThreadPool):
這種類型的線程池會(huì)一直保持固定數(shù)量的線程在池中,不會(huì)自動(dòng)回收線程。適用于需要限制同時(shí)執(zhí)行的任務(wù)數(shù)量的場(chǎng)景。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class FixedThreadPoolExample {public static void main(String[] args) {int numThreads = 5;ExecutorService executor = Executors.newFixedThreadPool(numThreads);// 提交任務(wù)到線程池for (int i = 0; i < 10; i++) {executor.submit(new MyRunnable(i));}executor.shutdown(); // 關(guān)閉線程池}
}
緩存線程池 (newCachedThreadPool):
緩存線程池會(huì)根據(jù)需要?jiǎng)?chuàng)建新的線程,如果線程池中的線程空閑時(shí)間超過(guò)指定的時(shí)間,則會(huì)被回收。適用于任務(wù)數(shù)量不確定,且需要自動(dòng)調(diào)整線程數(shù)的場(chǎng)景。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class CachedThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newCachedThreadPool();// 提交任務(wù)到線程池for (int i = 0; i < 10; i++) {executor.submit(new MyRunnable(i));}executor.shutdown(); // 關(guān)閉線程池}
}
單線程線程池 (newSingleThreadExecutor):
單線程線程池只有一個(gè)工作線程,適用于需要按順序執(zhí)行任務(wù)的場(chǎng)景。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class SingleThreadExecutorExample {public static void main(String[] args) {ExecutorService executor = Executors.newSingleThreadExecutor();// 提交任務(wù)到線程池for (int i = 0; i < 10; i++) {executor.submit(new MyRunnable(i));}executor.shutdown(); // 關(guān)閉線程池}
}
定時(shí)任務(wù)線程池 (newScheduledThreadPool):
定時(shí)任務(wù)線程池用于執(zhí)行定時(shí)任務(wù)和周期性任務(wù)。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolExample {public static void main(String[] args) {int numThreads = 3;ScheduledExecutorService executor = Executors.newScheduledThreadPool(numThreads);// 延遲1秒后執(zhí)行任務(wù)executor.schedule(new MyRunnable(1), 1, TimeUnit.SECONDS);// 延遲2秒后,每3秒執(zhí)行一次任務(wù)executor.scheduleAtFixedRate(new MyRunnable(2), 2, 3, TimeUnit.SECONDS);// 關(guān)閉線程池executor.shutdown();}
}
在這些示例中,MyRunnable是一個(gè)實(shí)現(xiàn)了Runnable接口的自定義任務(wù)類。創(chuàng)建線程池后,使用submit方法將任務(wù)提交給線程池進(jìn)行執(zhí)行,并最終調(diào)用shutdown方法關(guān)閉線程池。
這些Executors工廠方法提供了一些常見的線程池類型,但在某些情況下,可能需要更精細(xì)的線程池配置,這時(shí)可以考慮手動(dòng)創(chuàng)建ThreadPoolExecutor。
2、手動(dòng)創(chuàng)建ThreadPoolExecutor:
手動(dòng)創(chuàng)建 ThreadPoolExecutor 允許對(duì)線程池的各種參數(shù)進(jìn)行更精細(xì)的配置,以滿足特定的需求。以下是一個(gè)示例,演示如何手動(dòng)創(chuàng)建 ThreadPoolExecutor:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class ManualThreadPoolExecutorExample {public static void main(String[] args) {int corePoolSize = 5;int maxPoolSize = 10;long keepAliveTime = 60; // 60秒TimeUnit timeUnit = TimeUnit.SECONDS;BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, timeUnit, workQueue);// 提交任務(wù)到線程池for (int i = 0; i < 10; i++) {executor.submit(new MyRunnable(i));}executor.shutdown(); // 關(guān)閉線程池}
}class MyRunnable implements Runnable {private int id;public MyRunnable(int id) {this.id = id;}@Overridepublic void run() {System.out.println("Task " + id + " is running on thread " + Thread.currentThread().getName());}
}
在這個(gè)示例中,手動(dòng)創(chuàng)建了一個(gè) ThreadPoolExecutor,并配置了核心線程數(shù)、最大線程數(shù)、線程空閑時(shí)間等參數(shù)。然后,使用 submit 方法將任務(wù)提交給線程池進(jìn)行執(zhí)行,并最終調(diào)用 shutdown 方法關(guān)閉線程池。
注意,BlockingQueue 參數(shù)用于指定任務(wù)隊(duì)列,用來(lái)存儲(chǔ)等待執(zhí)行的任務(wù)。在這里,使用了 LinkedBlockingQueue,也可以選擇其他的實(shí)現(xiàn),如 ArrayBlockingQueue、PriorityBlockingQueue 等,以適應(yīng)不同的需求。
手動(dòng)創(chuàng)建 ThreadPoolExecutor 允許更精細(xì)地控制線程池的行為,但也需要更多的配置和管理。在選擇線程池類型和參數(shù)時(shí),應(yīng)根據(jù)應(yīng)用的特性和需求進(jìn)行調(diào)整。
3、使用ForkJoinPool:
ForkJoinPool 是 Java 提供的用于支持分治任務(wù)的線程池實(shí)現(xiàn)。它特別適用于能夠?qū)⑷蝿?wù)拆分成更小的子任務(wù),并且這些子任務(wù)可以并行執(zhí)行的情況。以下是一個(gè)使用 ForkJoinPool 創(chuàng)建線程池的示例:
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;public class ForkJoinPoolExample {public static void main(String[] args) {ForkJoinPool forkJoinPool = new ForkJoinPool();MyRecursiveAction task = new MyRecursiveAction(0, 10);forkJoinPool.invoke(task);forkJoinPool.shutdown();}
}class MyRecursiveAction extends RecursiveAction {private static final int THRESHOLD = 2; // 閾值,小于該值就不再分解任務(wù)private int start;private int end;public MyRecursiveAction(int start, int end) {this.start = start;this.end = end;}@Overrideprotected void compute() {if (end - start <= THRESHOLD) {// 執(zhí)行任務(wù)邏輯for (int i = start; i <= end; i++) {System.out.println("Task is running on thread " + Thread.currentThread().getName() + ": " + i);}} else {// 分解任務(wù)int mid = (start + end) / 2;MyRecursiveAction left = new MyRecursiveAction(start, mid);MyRecursiveAction right = new MyRecursiveAction(mid + 1, end);invokeAll(left, right);}}
}
在這個(gè)示例中,首先創(chuàng)建了一個(gè) ForkJoinPool 實(shí)例,然后定義了一個(gè)繼承自 RecursiveAction 的 MyRecursiveAction 類,用于表示要執(zhí)行的分治任務(wù)。在 compute 方法中,首先檢查任務(wù)是否足夠小,如果是,則執(zhí)行任務(wù)邏輯;否則,將任務(wù)分解為兩個(gè)子任務(wù)并使用 invokeAll 方法并行執(zhí)行。
ForkJoinPool 會(huì)根據(jù)任務(wù)的大小和可用線程數(shù)來(lái)動(dòng)態(tài)地調(diào)度任務(wù)的執(zhí)行,以獲得最佳的并行性能。在實(shí)際使用中,可以根據(jù)任務(wù)的特性和復(fù)雜度調(diào)整閾值,以及分解和執(zhí)行子任務(wù)的邏輯。
注意,ForkJoinPool 適用于能夠利用分治并行計(jì)算的場(chǎng)景,如遞歸問題的解決和并行計(jì)算任務(wù)。
4、使用 ScheduledThreadPoolExecutor 類
ScheduledThreadPoolExecutor 是 ThreadPoolExecutor 的子類,專門用于創(chuàng)建帶有定時(shí)任務(wù)功能的線程池。它可以執(zhí)行定時(shí)任務(wù)和周期性任務(wù)。以下是一個(gè)使用 ScheduledThreadPoolExecutor 創(chuàng)建線程池的示例:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class ScheduledThreadPoolExecutorExample {public static void main(String[] args) {int numThreads = 3;ScheduledExecutorService executor = Executors.newScheduledThreadPool(numThreads);// 延遲1秒后執(zhí)行任務(wù)executor.schedule(new MyRunnable(1), 1, TimeUnit.SECONDS);// 延遲2秒后,每3秒執(zhí)行一次任務(wù)executor.scheduleAtFixedRate(new MyRunnable(2), 2, 3, TimeUnit.SECONDS);// 關(guān)閉線程池executor.shutdown();}
}class MyRunnable implements Runnable {private int id;public MyRunnable(int id) {this.id = id;}@Overridepublic void run() {System.out.println("Task " + id + " is running on thread " + Thread.currentThread().getName());}
}
在這個(gè)示例中,使用 Executors.newScheduledThreadPool() 方法創(chuàng)建了一個(gè) ScheduledExecutorService,然后使用 schedule 方法在指定的延遲時(shí)間后執(zhí)行一次任務(wù),使用 scheduleAtFixedRate 方法在指定的延遲時(shí)間后開始執(zhí)行任務(wù),并且每隔一段時(shí)間重復(fù)執(zhí)行。
ScheduledThreadPoolExecutor 可以滿足定時(shí)任務(wù)和周期性任務(wù)的需求,它能夠自動(dòng)調(diào)度任務(wù)的執(zhí)行。當(dāng)任務(wù)執(zhí)行時(shí)間超過(guò)任務(wù)間隔時(shí)間時(shí),ScheduledThreadPoolExecutor 會(huì)等待當(dāng)前任務(wù)完成后再啟動(dòng)下一個(gè)任務(wù)。這種特性對(duì)于需要保證任務(wù)執(zhí)行間隔的場(chǎng)景非常有用。
5、使用第三方庫(kù)(如ThreadPoolExecutor的封裝庫(kù)):
許多第三方庫(kù)都提供了對(duì) ThreadPoolExecutor 的封裝,以便更方便地創(chuàng)建和管理線程池。其中一個(gè)常用的庫(kù)是 Apache Commons Lang 中的 ThreadPoolExecutor,它提供了一些額外的功能和配置選項(xiàng)。以下是一個(gè)使用 Apache Commons Lang 的 ThreadPoolExecutor 封裝庫(kù)的示例:
首先,確保已經(jīng)將 Apache Commons Lang 庫(kù)添加到項(xiàng)目中。然后,你可以使用 org.apache.commons.lang3.concurrent.BasicThreadFactory 來(lái)創(chuàng)建線程池。下面是示例代碼:
import org.apache.commons.lang3.concurrent.BasicThreadFactory;import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class ThirdPartyThreadPoolExample {public static void main(String[] args) {int numThreads = 3;BasicThreadFactory factory = new BasicThreadFactory.Builder().namingPattern("my-pool-%d").daemon(true).build();ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(numThreads, factory);// 延遲1秒后執(zhí)行任務(wù)executor.schedule(new MyRunnable(1), 1, TimeUnit.SECONDS);// 延遲2秒后,每3秒執(zhí)行一次任務(wù)executor.scheduleAtFixedRate(new MyRunnable(2), 2, 3, TimeUnit.SECONDS);// 關(guān)閉線程池executor.shutdown();}
}class MyRunnable implements Runnable {private int id;public MyRunnable(int id) {this.id = id;}@Overridepublic void run() {System.out.println("Task " + id + " is running on thread " + Thread.currentThread().getName());}
}
在這個(gè)示例中,使用 BasicThreadFactory 來(lái)配置線程池。通過(guò)設(shè)置不同的屬性,可以定制線程名、守護(hù)線程屬性等。然后,使用 ScheduledThreadPoolExecutor 創(chuàng)建一個(gè)帶有定時(shí)任務(wù)功能的線程池,并使用 schedule 和 scheduleAtFixedRate 方法添加定時(shí)任務(wù)。
使用第三方庫(kù)的線程池封裝可以幫助更方便地創(chuàng)建和管理線程池,以及提供一些額外的功能選項(xiàng)。