Spring 與 JDK 線程池的簡單使用示例詳解
1.配置自定義共享線程池(Spring線程池)
@Configuration
@EnableAsync
public class ThreadPoolConfig{
//主要任務(wù)的調(diào)度,計劃執(zhí)行
@Bean("taskScheduler")
public Executor createScheduler(){
// 創(chuàng)建一個線程池對象
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
// 定義一個線程池大小
scheduler.setPoolSize(100);
// 線程池名的前綴
scheduler.setThreadNamePrefix("taskScheduler-");
// 設(shè)置線程池關(guān)閉的時候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean
scheduler.setWaitForTasksToCompleteOnShutdown(true);
// 設(shè)置線程池中任務(wù)的等待時間,如果超過這個時候還沒有銷毀就強制銷毀,以確保應(yīng)用最后能夠被關(guān)閉,而不是阻塞住
scheduler.setAwaitTerminationSeconds(60);
// 線程池對拒絕任務(wù)的處理策略,當線程池沒有處理能力的時候,該策略會直接在 execute 方法的調(diào)用線程中運行被拒絕的任務(wù);如果執(zhí)行程序已關(guān)閉,則會丟棄該任務(wù)
scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return scheduler;
}
//主要任務(wù)的執(zhí)行
@Bean("taskExecutor")
public Executor createExecutor(){
// 創(chuàng)建一個線程池對象
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心線程池大小
executor.setCorePoolSize(10);
//最大線程數(shù)
executor.setMaxPoolSize(30);
//隊列容量
executor.setQueueCapacity(100);
//活躍時間
executor.setKeepAliveSeconds(60);
//線程名字前綴
executor.setThreadNamePrefix("taskExecutor-");
// 設(shè)置線程池關(guān)閉的時候等待所有任務(wù)都完成再繼續(xù)銷毀其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
// 線程池對拒絕任務(wù)的處理策略,當線程池沒有處理能力的時候,該策略會直接在 execute 方法的調(diào)用線程中運行被拒絕的任務(wù);如果執(zhí)行程序已關(guān)閉,則會丟棄該任務(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實現(xiàn)類)
3.計算結(jié)果(返回結(jié)果 Future接口,F(xiàn)utureTask實現(xiàn)類)
===============Executors現(xiàn)成的線程池========jdk自帶線程池====
1 Executors.FixedThreadPool 核心數(shù)=容納的最大線程數(shù)=N
無界隊列(當隊列過多時,會造成無限循環(huán))
2 Executors.CachedThreadPool 容納的最大線程數(shù)=無界
主線程提交任務(wù)的速度高于 maximumPoolSize中線程處理任務(wù)的速度時 CachedThreadPool將會不斷的創(chuàng)建新的線程,
在極端情況下,
CachedThreadPool會因為創(chuàng)建過多線程而耗盡CPU和內(nèi)存資源
3 Executors.SingleThreadExecutor 核心數(shù)=容納的最大線程數(shù)=1 始終保持只有一個線程在執(zhí)行
無界隊列(當隊列過多時,會造成無限循環(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)用線程中運行被拒絕的任務(wù)。
DiscardOldestPolicy:放棄最舊的未處理請求,重試execute。
DiscardPolicy:丟棄被拒絕的任務(wù)。
================處理流程===================jdk 與 spring =====================
1.核心線程池是否在執(zhí)行任務(wù),不在執(zhí)行就選一條線程執(zhí)行,否則查看核心線程池是否已滿
2.核心線程池是否滿,不滿則創(chuàng)建一條線程執(zhí)行,否值查看隊列是否已滿
3.隊列是否滿,隊列不滿加入隊列,否則查看線程池是否已滿
4.線程池是否已滿,線程池不滿創(chuàng)建一條線程池,否則根據(jù)決絕策略處理
# 1.當一個任務(wù)被提交到線程池時,首先查看線程池的核心線程是否都在執(zhí)行任務(wù),否就選擇一條線程執(zhí)行任務(wù),是就執(zhí)行第二步。
# 2.查看核心線程池是否已滿,不滿就創(chuàng)建一條線程執(zhí)行任務(wù),否則執(zhí)行第三步。
# 3.查看任務(wù)隊列是否已滿,不滿就將任務(wù)存儲在任務(wù)隊列中,否則執(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整合注解,詳細的介紹了ssm框架的使用,具有一定的參考價值,有興趣的可以了解一下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é)合一個求1~10的整數(shù)和的例子來幫助大家理解while循環(huán)的用法,感興趣的朋友跟隨小編來看看吧2020-11-11
Mybatis-Plus @TableField自動填充時間為null的問題解決
本文主要介紹了Mybatis-Plus @TableField自動填充時間為null的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-01-01
Java使用System.currentTimeMillis()方法計算程序運行時間的示例代碼
System.currentTimeMillis() 方法的返回類型為 long ,表示毫秒為單位的當前時間,文中通過示例代碼介紹了計算 String 類型與 StringBuilder 類型拼接字符串的耗時情況,對Java計算程序運行時間相關(guān)知識感興趣的朋友一起看看吧2022-03-03

