1. 認識java線程池
1.1 在什么情況下使用線程池?
1.2 使用線程池的好處:
1.3 線程池包括以下四個基本組成部分:
1.4 線程池的核心參數(shù)
ThreadPoolExecutor 有四個構(gòu)造方法,前三個都是調(diào)用最后一個(最后一個參數(shù)最全)
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); } // 都調(diào)用它 public ThreadPoolExecutor(// 核心線程數(shù) int corePoolSize, // 最大線程數(shù) int maximumPoolSize, // 閑置線程存活時間 long keepAliveTime, // 時間單位 TimeUnit unit, // 線程隊列 BlockingQueue<Runnable> workQueue, // 線程工廠 ThreadFactory threadFactory, // 隊列已滿,而且當(dāng)前線程數(shù)已經(jīng)超過最大線程數(shù)時的異常處理策略 RejectedExecutionHandler handler ) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
主要參數(shù)
corePoolSize:核心線程數(shù)
maxPoolSize:最大線程數(shù)
keepAliveTime:線程空閑時間
workQueue:一個阻塞隊列,用來存儲等待執(zhí)行的任務(wù),這個參數(shù)的選擇也很重要,會對線程池的運行過程產(chǎn)生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:
關(guān)于阻塞隊列可以看這篇:java 阻塞隊列
threadFactory:線程工廠,主要用來創(chuàng)建線程;
rejectedExecutionHandler:任務(wù)拒絕處理器,兩種情況會拒絕處理任務(wù):
當(dāng)拒絕處理任務(wù)時線程池會調(diào)用rejectedExecutionHandler來處理這個任務(wù)。如果沒有設(shè)置默認是AbortPolicy,會拋出異常。ThreadPoolExecutor類有幾個內(nèi)部實現(xiàn)類來處理這類情況:
1.5 Java線程池 ExecutorService
備注:Executors只是一個工廠類,它所有的方法返回的都是ThreadPoolExecutor、ScheduledThreadPoolExecutor這兩個類的實例。
1.6 ExecutorService有如下幾個執(zhí)行方法
execute(Runnable)
這個方法接收一個Runnable實例,并且異步的執(zhí)行
executorService.execute(new Runnable() {public void run() { System.out.println("Asynchronous task");}});executorService.shutdown();
submit(Runnable)
submit(Runnable)和execute(Runnable)區(qū)別是前者可以返回一個Future對象,通過返回的Future對象,我們可以檢查提交的任務(wù)是否執(zhí)行完畢,請看下面執(zhí)行的例子:
Future future = executorService.submit(new Runnable() {public void run() { System.out.println("Asynchronous task");}});future.get(); //returns null if the task has finished correctly.
submit(Callable)
submit(Callable)和submit(Runnable)類似,也會返回一個Future對象,但是除此之外,submit(Callable)接收的是一個Callable的實現(xiàn),Callable接口中的call()方法有一個返回值,可以返回任務(wù)的執(zhí)行結(jié)果,而Runnable接口中的run()方法是void的,沒有返回值。請看下面實例:
Future future = executorService.submit(new Callable(){public Object call() throws Exception { System.out.println("Asynchronous Callable"); return "Callable Result";}});System.out.println("future.get() = " + future.get());
如果任務(wù)執(zhí)行完成,future.get()方法會返回Callable任務(wù)的執(zhí)行結(jié)果。注意,future.get()方法會產(chǎn)生阻塞。
invokeAny(…)
invokeAny(…)方法接收的是一個Callable的集合,執(zhí)行這個方法不會返回Future,但是會返回所有Callable任務(wù)中其中一個任務(wù)的執(zhí)行結(jié)果。這個方法也無法保證返回的是哪個任務(wù)的執(zhí)行結(jié)果,反正是其中的某一個。
ExecutorService executorService = Executors.newSingleThreadExecutor();Set<Callable<String>> callables = new HashSet<Callable<String>>();callables.add(new Callable<String>() {public String call() throws Exception { return "Task 1";}});callables.add(new Callable<String>() {public String call() throws Exception { return "Task 2";}});callables.add(new Callable<String>() { public String call() throws Exception { return "Task 3";}});String result = executorService.invokeAny(callables);System.out.println("result = " + result);executorService.shutdown();
invokeAll(…)
invokeAll(…)與 invokeAny(…)類似也是接收一個Callable集合,但是前者執(zhí)行之后會返回一個Future的List,其中對應(yīng)著每個Callable任務(wù)執(zhí)行后的Future對象。
List<Future<String>> futures = executorService.invokeAll(callables);for(Future<String> future : futures){System.out.println("future.get = " + future.get());}executorService.shutdown();
2. 在springBoot中使用java線程池ExecutorService
2.1 springBoot 的使用配置
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/** * 數(shù)據(jù)收集配置,主要作用在于Spring啟動時自動加載一個ExecutorService對象. * @author Bruce * @date 2017/2/22 * update by Cliff at 2027/11/03 */@Configurationpublic class ThreadPoolConfig { @Bean public ExecutorService getThreadPool(){ return Executors.newFixedThreadPool(); }}
2.2 使用
在@service 中注入 ExecutorService 然后就可以直接用了。 @Autowired private ExecutorService executorService;public void test(){ executorService.execute(new Runnable() { public void run() { System.out.println("Asynchronous task"); } }); }
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對VeVb武林網(wǎng)的支持。
新聞熱點
疑難解答
圖片精選