Spring 与 JDK 线程池的简单使用示例详解
作者:羁客% 发布时间:2023-08-20 04:02:59
1.配置自定义共享线程池(Spring线程池)
@Configuration
@EnableAsync
public class ThreadPoolConfig{
//主要任务的调度,计划执行
@Bean("taskScheduler")
public Executor createScheduler(){
// 创建一个线程池对象
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
// 定义一个线程池大小
scheduler.setPoolSize(100);
// 线程池名的前缀
scheduler.setThreadNamePrefix("taskScheduler-");
// 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
scheduler.setWaitForTasksToCompleteOnShutdown(true);
// 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
scheduler.setAwaitTerminationSeconds(60);
// 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
scheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return scheduler;
}
//主要任务的执行
@Bean("taskExecutor")
public Executor createExecutor(){
// 创建一个线程池对象
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程池大小
executor.setCorePoolSize(10);
//最大线程数
executor.setMaxPoolSize(30);
//队列容量
executor.setQueueCapacity(100);
//活跃时间
executor.setKeepAliveSeconds(60);
//线程名字前缀
executor.setThreadNamePrefix("taskExecutor-");
// 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
executor.setWaitForTasksToCompleteOnShutdown(true);
// 线程池对拒绝任务的处理策略,当线程池没有处理能力的时候,该策略会直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
2.编写执行任务对象与具体任务逻辑方法
@Component
public class TaskComponent{
@Async("taskExecutor")
public void doTaskExecutor() {
System.out.println("任务开始执行!!!");
//具体的执行任务
//。。。。。。。
}
// //有返回值(ObjectVo为自己定义的返回类型)
//@Async("taskExecutor")
//public Future<ObjectVo> doTaskExecutor() {
//System.out.println("任务开始执行!!!");
// //具体的执行任务
////。。。。。。。
//ObjectVo result=new ObjectVo();
//return new AsyncResult<>(result);
//}
@Async("taskScheduler")
public void doTaskScheduler() {
System.out.println("任务开始调度!!!");
//具体的调度任务
//。。。。。。。
}
// //有返回值(ObjectVo为自己定义的返回类型)
//@Async("taskScheduler")
//public Future<ObjectVo> doTaskScheduler() {
//System.out.println("任务开始调度!!!");
// //具体的调度任务
////。。。。。。。
//ObjectVo result=new ObjectVo();
//return new AsyncResult<>(result);
//}
}
3.调用任务方法(在哪调用都可以,根据自己业务需求在合适的地方调用即可)
@Service
public class UserServiceImpl implements UserService{
@Autowired
private TaskComponent taskComponent;
//测试任务执行与调用
@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结构========jdk自带线程池==========
1.任务(Runnable,Callable)
2.任务的执行(Executor,ExecutorService 接口,ThreadPoolExecutor,ScheduledThreadExecutor实现类)
3.计算结果(返回结果 Future接口,FutureTask实现类)
===============Executors现成的线程池========jdk自带线程池====
1 Executors.FixedThreadPool 核心数=容纳的最大线程数=N
* 队列(当队列过多时,会造成无限循环)
2 Executors.CachedThreadPool 容纳的最大线程数= *
主线程提交任务的速度高于 maximumPoolSize中线程处理任务的速度时 CachedThreadPool将会不断的创建新的线程,
在极端情况下,
CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源
3 Executors.SingleThreadExecutor 核心数=容纳的最大线程数=1 始终保持只有一个线程在执行
* 队列(当队列过多时,会造成无限循环)
===============自定义Executors===========jdk自带线程池====================
ExecuteService threadPool = new ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler);
//设置线程池的前缀
ThreadFactory threadFactory = new ThreadFactoryBuilder()
.setNameFormat("trhead-pool-%d").build();
//设置决绝策略
RejectedExecutionHandler:
AbortPolicy:抛出RejectedExecutionException
CallerRunsPolicy:直接在execute方法的调用线程中运行被拒绝的任务。
DiscardOldestPolicy:放弃最旧的未处理请求,重试execute。
DiscardPolicy:丢弃被拒绝的任务。
================处理流程===================jdk 与 spring =====================
1.核心线程池是否在执行任务,不在执行就选一条线程执行,否则查看核心线程池是否已满
2.核心线程池是否满,不满则创建一条线程执行,否值查看队列是否已满
3.队列是否满,队列不满加入队列,否则查看线程池是否已满
4.线程池是否已满,线程池不满创建一条线程池,否则根据决绝策略处理
# 1.当一个任务被提交到线程池时,首先查看线程池的核心线程是否都在执行任务,否就选择一条线程执行任务,是就执行第二步。
# 2.查看核心线程池是否已满,不满就创建一条线程执行任务,否则执行第三步。
# 3.查看任务队列是否已满,不满就将任务存储在任务队列中,否则执行第四步。
# 4.查看线程池是否已满,不满就创建一条线程执行任务,否则就按照策略(拒绝策略)处理无法执行的任务。
来源:https://blog.csdn.net/qq_37778018/article/details/126767305


猜你喜欢
- 本文解析了C# KeyUp事件中MessageBox的回车(Enter)键出现回调问题的解决办法。具体问题如下:在一个窗体上有一个名为txt
- 首先对图片进行UUID 防止图片被覆盖以及爬图UUID的生成规则:日期时间,MAC地址,HashCode,随机数(多种之一)开发上传接口,两
- 在Java编程过程中,我们常常会遇到比较基本类型或者对象之间的大小关系,下面我们来看看怎么去比较。源码如下:package object;c
- Java集合是java提供的工具包,包含了常用的数据结构:集合、链表、队列、栈、数组、映射等。Java集合工具包位置是java.util.*
- 这篇文章主要介绍了Spring Boot Debug调试过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- MyBatis缓存我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO
- 题记:由于业务的需要,需要根据模板定制pdf文档,经测试根据模板导出word成功了;但是导出pdf相对麻烦了一点。两天的研究测试java导出
- 前言最近搭建的springbootboot的网关,配置请求路径,竟然没有生效现象配置文件如下:启动类,控制台打印的结果如下:我随便更换端口都
- 本文实例讲述了Android使用Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素的解
- 定义广播 * 的Action:private static final String TAG ="SmsService"
- 这是之前软工课设我写的java访问mysql工具类,它经过了多轮的测试,应该能够适应大多数的操作需求。比之前大二写的更鲁棒,更易用。pack
- 用伪语句可以表示如下public bitmap GrayScal(bitmap orgbmp){ 建立一
- 前言本文主要介绍了如果通过输入年份月份输出天数的相关内容,下面话不多说了,来一起看看详细的介绍吧示例代码package com.ambow.
- 下面讲解以下在使用listview时最常见的几个问题。1.如何改变item的背景色和按下颜色listview默认情况下,item的背景色是黑
- 本文实例讲述了Android编程之短信列表的时间显示。分享给大家供大家参考,具体如下:Android的短信的时间的显示做的很精细,首先保存在
- 题目:求1+2!+3!+...+20!的和程序分析:此程序只是把累加变成了累乘。程序设计:public class Ex21 {  
- ButterKnife 算是一款知名老牌 Android 开发框架了,通过注解绑定视图,避免了 findViewById() 的操作,广受好
- 本文实例为大家分享了java生成字母验证码的具体代码,供大家参考,具体内容如下import java.awt.BasicStroke;imp
- zookeeper集群配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读
- 在文件夹中,我们经常有类似s_1.txt、s_2.txt、s_10.txt、s_11.txt这样的命名方式,我们期望的排序方式是s_1.tx