Spring 與 JDK 線程池的簡單使用示例詳解
1.配置自定義共享線程池(Spring線程池)
@Configuration @EnableAsync public class ThreadPoolConfig{ //主要任務(wù)的調(diào)度,計(jì)劃執(zhí)行 @Bean("taskScheduler") public Executor createScheduler(){ // 創(chuàng)建一個(gè)線程池對象 ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); // 定義一個(gè)線程池大小 scheduler.setPoolSize(100); // 線程池名的前綴 scheduler.setThreadNamePrefix("taskScheduler-"); // 設(shè)置線程池關(guān)閉的時(shí)候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean scheduler.setWaitForTasksToCompleteOnShutdown(true); // 設(shè)置線程池中任務(wù)的等待時(shí)間,如果超過這個(gè)時(shí)候還沒有銷毀就強(qiáng)制銷毀,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住 scheduler.setAwaitTerminationSeconds(60); // 線程池對拒絕任務(wù)的處理策略,當(dāng)線程池沒有處理能力的時(shí)候,該策略會(huì)直接在 execute 方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù);如果執(zhí)行程序已關(guān)閉,則會(huì)丟棄該任務(wù) scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return scheduler; } //主要任務(wù)的執(zhí)行 @Bean("taskExecutor") public Executor createExecutor(){ // 創(chuàng)建一個(gè)線程池對象 ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心線程池大小 executor.setCorePoolSize(10); //最大線程數(shù) executor.setMaxPoolSize(30); //隊(duì)列容量 executor.setQueueCapacity(100); //活躍時(shí)間 executor.setKeepAliveSeconds(60); //線程名字前綴 executor.setThreadNamePrefix("taskExecutor-"); // 設(shè)置線程池關(guān)閉的時(shí)候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean executor.setWaitForTasksToCompleteOnShutdown(true); // 線程池對拒絕任務(wù)的處理策略,當(dāng)線程池沒有處理能力的時(shí)候,該策略會(huì)直接在 execute 方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù);如果執(zhí)行程序已關(guān)閉,則會(huì)丟棄該任務(wù) executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } }
2.編寫執(zhí)行任務(wù)對象與具體任務(wù)邏輯方法
@Component public class TaskComponent{ @Async("taskExecutor") public void doTaskExecutor() { System.out.println("任務(wù)開始執(zhí)行?。?!"); //具體的執(zhí)行任務(wù) //。。。。。。。 } // //有返回值(ObjectVo為自己定義的返回類型) //@Async("taskExecutor") //public Future<ObjectVo> doTaskExecutor() { // System.out.println("任務(wù)開始執(zhí)行!??!"); // //具體的執(zhí)行任務(wù) // //。。。。。。。 // ObjectVo result=new ObjectVo(); // return new AsyncResult<>(result); //} @Async("taskScheduler") public void doTaskScheduler() { System.out.println("任務(wù)開始調(diào)度!??!"); //具體的調(diào)度任務(wù) //。。。。。。。 } // //有返回值(ObjectVo為自己定義的返回類型) //@Async("taskScheduler") //public Future<ObjectVo> doTaskScheduler() { // System.out.println("任務(wù)開始調(diào)度?。?!"); // //具體的調(diào)度任務(wù) // //。。。。。。。 // ObjectVo result=new ObjectVo(); // return new AsyncResult<>(result); //} }
3.調(diào)用任務(wù)方法(在哪調(diào)用都可以,根據(jù)自己業(yè)務(wù)需求在合適的地方調(diào)用即可)
@Service public class UserServiceImpl implements UserService{ @Autowired private TaskComponent taskComponent; //測試任務(wù)執(zhí)行與調(diào)用 @SneakyThrows @Override public void testTask(){ //沒有返回值 taskComponent.doTaskExecutor(); taskComponent.doTaskScheduler(); //有返回值 //Future<ObjectVo> executorResult = taskComponent.doTaskExecutor(); //Future<ObjectVo> schedulerResult = taskComponent.doTaskScheduler(); //System.out.println(executorResult.get()); //System.out.println(schedulerResult.get()); } }
===============Executors結(jié)構(gòu)========jdk自帶線程池==========
1.任務(wù)(Runnable,Callable)
2.任務(wù)的執(zhí)行(Executor,ExecutorService 接口,ThreadPoolExecutor,ScheduledThreadExecutor實(shí)現(xiàn)類)
3.計(jì)算結(jié)果(返回結(jié)果 Future接口,F(xiàn)utureTask實(shí)現(xiàn)類)
===============Executors現(xiàn)成的線程池========jdk自帶線程池====
1 Executors.FixedThreadPool 核心數(shù)=容納的最大線程數(shù)=N
無界隊(duì)列(當(dāng)隊(duì)列過多時(shí),會(huì)造成無限循環(huán))
2 Executors.CachedThreadPool 容納的最大線程數(shù)=無界
主線程提交任務(wù)的速度高于 maximumPoolSize中線程處理任務(wù)的速度時(shí) CachedThreadPool將會(huì)不斷的創(chuàng)建新的線程,
在極端情況下,
CachedThreadPool會(huì)因?yàn)閯?chuàng)建過多線程而耗盡CPU和內(nèi)存資源
3 Executors.SingleThreadExecutor 核心數(shù)=容納的最大線程數(shù)=1 始終保持只有一個(gè)線程在執(zhí)行
無界隊(duì)列(當(dāng)隊(duì)列過多時(shí),會(huì)造成無限循環(huán))
===============自定義Executors===========jdk自帶線程池====================
ExecuteService threadPool = new ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
//設(shè)置線程池的前綴
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("trhead-pool-%d").build();
//設(shè)置決絕策略
RejectedExecutionHandler:
AbortPolicy:拋出RejectedExecutionException
CallerRunsPolicy:直接在execute方法的調(diào)用線程中運(yùn)行被拒絕的任務(wù)。
DiscardOldestPolicy:放棄最舊的未處理請求,重試execute。
DiscardPolicy:丟棄被拒絕的任務(wù)。
================處理流程===================jdk 與 spring =====================
1.核心線程池是否在執(zhí)行任務(wù),不在執(zhí)行就選一條線程執(zhí)行,否則查看核心線程池是否已滿
2.核心線程池是否滿,不滿則創(chuàng)建一條線程執(zhí)行,否值查看隊(duì)列是否已滿
3.隊(duì)列是否滿,隊(duì)列不滿加入隊(duì)列,否則查看線程池是否已滿
4.線程池是否已滿,線程池不滿創(chuàng)建一條線程池,否則根據(jù)決絕策略處理
# 1.當(dāng)一個(gè)任務(wù)被提交到線程池時(shí),首先查看線程池的核心線程是否都在執(zhí)行任務(wù),否就選擇一條線程執(zhí)行任務(wù),是就執(zhí)行第二步。
# 2.查看核心線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則執(zhí)行第三步。
# 3.查看任務(wù)隊(duì)列是否已滿,不滿就將任務(wù)存儲(chǔ)在任務(wù)隊(duì)列中,否則執(zhí)行第四步。
# 4.查看線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則就按照策略(拒絕策略)處理無法執(zhí)行的任務(wù)。
到此這篇關(guān)于Spring 與 JDK 線程池的簡單使用的文章就介紹到這了,更多相關(guān)Spring 與 JDK 線程池內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解spring+springmvc+mybatis整合注解
本篇文章主要介紹了詳解spring+springmvc+mybatis整合注解,詳細(xì)的介紹了ssm框架的使用,具有一定的參考價(jià)值,有興趣的可以了解一下2017-04-04詳解Java中while和do-while循環(huán)、break的使用
本文介紹了循環(huán)結(jié)構(gòu)語句while和do-while循環(huán)、break的使用,while循環(huán)語句通過流程圖和語法語句結(jié)合一個(gè)求1~10的整數(shù)和的例子來幫助大家理解while循環(huán)的用法,感興趣的朋友跟隨小編來看看吧2020-11-11Mybatis-Plus @TableField自動(dòng)填充時(shí)間為null的問題解決
本文主要介紹了Mybatis-Plus @TableField自動(dòng)填充時(shí)間為null的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01java 中RSA的方式實(shí)現(xiàn)非對稱加密的實(shí)例
這篇文章主要介紹了java 中RSA的方式實(shí)現(xiàn)非對稱加密的實(shí)例的相關(guān)資料,這里提供實(shí)例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08Java使用System.currentTimeMillis()方法計(jì)算程序運(yùn)行時(shí)間的示例代碼
System.currentTimeMillis() 方法的返回類型為 long ,表示毫秒為單位的當(dāng)前時(shí)間,文中通過示例代碼介紹了計(jì)算 String 類型與 StringBuilder 類型拼接字符串的耗時(shí)情況,對Java計(jì)算程序運(yùn)行時(shí)間相關(guān)知識感興趣的朋友一起看看吧2022-03-03Java多線程實(shí)戰(zhàn)之交叉打印的兩種方法
今天小編就為大家分享一篇關(guān)于Java多線程實(shí)戰(zhàn)之交叉打印的兩種方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02