Java和Spring中线程池创建方法
一、線程池定義
1.JDK中線程池類圖
Executor:父接口,所有線程池都實(shí)現(xiàn)了這個(gè)接口,里面有一個(gè)excute()方法用于執(zhí)行線程
ExecutorService:線程池接口,繼承自Executor接口,供了生命周期管理的方法,返回 Future 對象,可以返回執(zhí)行完的結(jié)果
ThreadPoolExecutor:線程池的具體實(shí)現(xiàn)類,一般使用ThreadPoolExecutor創(chuàng)建線程池
?
2.創(chuàng)建線程池的工具類
Executors:線程池的工具類,用于創(chuàng)建線程池,返回ExecutorService類型的線程池
1)public static ExecutorService newFiexedThreadPool(int Threads) :創(chuàng)建固定數(shù)目線程的線程池
2)public static ExecutorService newCachedThreadPool():創(chuàng)建一個(gè)可緩存的線程池,調(diào)用execute 將重用以前構(gòu)造的線程(如果線程可用)。如果沒有可用的線程,則創(chuàng)建一個(gè)新線程并添加到池中。終止并從緩存中移除那些已有 60 秒鐘未被使用的線程
3)public static ExecutorService newSingleThreadExecutor():創(chuàng)建一個(gè)單線程化的Executor
4)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):調(diào)度型線程池
3.區(qū)別
1)Executor 接口定義了 execute()方法用來接收一個(gè)Runnable接口的對象,不接受返回的對象,而 ExecutorService 接口中的 submit()方法可以通過Future 對象接受Runnable和Callable接口的對象
2)ExecutorService 還提供用來控制線程池的方法。比如:調(diào)用 shutDown() 方法終止線程池
3)Executors 類提供工廠方法用來創(chuàng)建不同類型的線程池
4.線程池參數(shù)
corePoolSize:核心線程數(shù)
maximumPoolSize, //最大線程數(shù)
keepAliveTime:當(dāng)線程數(shù)超過核心線程數(shù),線程的最大存活時(shí)間
unit:keepAliveTime的時(shí)間單位
workQueue:阻塞隊(duì)列
threadFactory: 創(chuàng)建線程的工廠
handler:拒絕策略
5.線程池執(zhí)行順序
1)當(dāng)線程數(shù)小于 corePoolSize時(shí),創(chuàng)建線程執(zhí)行任務(wù)。
2)當(dāng)線程數(shù)大于等于 corePoolSize并且 workQueue 沒有滿時(shí),放入workQueue中
3)線程數(shù)大于等于 corePoolSize并且當(dāng) workQueue 滿時(shí),新任務(wù)新建線程運(yùn)行,線程總數(shù)要小于 maximumPoolSize
4)當(dāng)線程總數(shù)等于 maximumPoolSize 并且 workQueue 滿了的時(shí)候執(zhí)行 handler 的 rejectedExecution。也就是拒絕策略
6.拒絕訪問策略
ThreadPoolExecutor默認(rèn)有四個(gè)拒絕策略:
1、ThreadPoolExecutor.AbortPolicy() 直接拋出異常RejectedExecutionException
2、ThreadPoolExecutor.CallerRunsPolicy() 直接調(diào)用run方法并且阻塞執(zhí)行
3、ThreadPoolExecutor.DiscardPolicy() 直接丟棄后來的任務(wù)
4、ThreadPoolExecutor.DiscardOldestPolicy() 丟棄在隊(duì)列中隊(duì)首的任務(wù)
當(dāng)然可以自己繼承RejectedExecutionHandler來寫拒絕策略.
?
二、線程池使用方法
1.Java JDK創(chuàng)建線程池的方法-ThreadPoolExecutor
1)使用ThreadPoolExecutor創(chuàng)建線程池
API如下所示:
public ThreadPoolExecutor(int corePoolSize, ?//核心線程數(shù)int maximumPoolSize, //最大線程數(shù)long keepAliveTime, ? //當(dāng)線程數(shù)超過核心線程數(shù),線程的最大存活時(shí)間TimeUnit unit, ? ? ? ?//keepAliveTime的時(shí)間單位BlockingQueue<Runnable> workQueue) //阻塞隊(duì)列容量{?this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), defaultHandler); }所在包:java.util.concurrent.*
2)代碼實(shí)現(xiàn):
3)結(jié)果展示:
?
2.Spring創(chuàng)建線程池方式-ThreadPoolTaskExecutor
所在包:package org.springframework.core.task;
創(chuàng)建線程池并注入spring容器,開啟@EnableAsync注解方便后續(xù)使用它@Async異步化調(diào)用
?
3.異步調(diào)用線程池線程方法-ThreadPoolTaskExecutor
1)代碼處使用
需要使用@Autowired裝配獲取注入的線程池對象
? @Autowiredprivate ThreadPoolTaskExecutor executor; ?/*** 根據(jù)活動(dòng)id獲取指定活動(dòng),異步添加緩存操作*/@RequestMapping("/test9")public String testTaskExecutor() throws Throwable {log.info("進(jìn)入方法:");//異步調(diào)用executor.execute(() -> {try {log.info("進(jìn)入異步方法:");Thread.sleep(2000);jedisClusterClient.getJedisCluster().set("test9:async", "test"); ?} catch (InterruptedException e) {e.printStackTrace();}System.out.println("異步執(zhí)行添加緩存:" + jedisClusterClient.getJedisCluster().get("test9:async"));});log.info("方法執(zhí)行完畢");return "test";}執(zhí)行結(jié)果:
可以看到異步執(zhí)行是在方法執(zhí)行完畢后才執(zhí)行的,不是同步的,異步化成功
2)使用@Async注解異步調(diào)用
注意:@Async修飾的方法的實(shí)例必須注入spring容器中方能使用,代碼如下:
異步方法使用@Async調(diào)用:
執(zhí)行結(jié)果:
可以看到結(jié)果也是異步化調(diào)用
總結(jié)
以上是生活随笔為你收集整理的Java和Spring中线程池创建方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis之PageHelper分页
- 下一篇: Java基础知识——异常Throwabl