springBoot 的默认线程池-ThreadPoolTaskExecutor
Posted 栗子~~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springBoot 的默认线程池-ThreadPoolTaskExecutor相关的知识,希望对你有一定的参考价值。
文章目录
前言
如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!
springBoot 的默认线程池
01 ThreadPoolTaskExecutor是什么?
hreadPoolTaskExecutor是spring core包中的,
ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装,
是sring为我们提供的线程池类。
02 实战
02::01 配置
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author yangzhenyu
* @version 1.0
* @description: springBoot 默认线程池
* @date 2022/9/13 16:56
*/
@Configuration
@EnableAsync
public class ThreadPoolTaskExecutorConfig
@Bean("poolTaskExecutor")
public ThreadPoolTaskExecutor taskExecutor()
ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
threadPoolExecutor = new ThreadPoolTaskExecutor();
//核心线程数
threadPoolExecutor.setCorePoolSize(5);
//最大线程数
threadPoolExecutor.setMaxPoolSize(5);
//允许线程最大空闲时间、默认为秒
threadPoolExecutor.setKeepAliveSeconds(5);
//缓存队列大小
threadPoolExecutor.setQueueCapacity(5000);
//线程池对拒绝任务的处理策略 - 始终抛出RejectedExecutionException
threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
//线程池名前缀
//threadPoolExecutor.setThreadNamePrefix(THREAD_NAME_PREFIX);
threadPoolExecutor.setThreadFactory(new ThreadFactoryBuilder().setNameFormat("yzy-Async-%d").build());
/**
* taskDecorator主要是对Runnable任务装饰一下, 在任务执行时完成异常日志打印、ThreadLocal清理等功能
* 但是对Callable任务(由submit()方法提交的任务),这个taskDecorator虽然也能装饰,但是并不能捕获异常,
* 因为类似FutureTask的run方法内部自己补获了异常,不会抛出到afterExecute方法中
*/
// 增加 TaskDecorator 属性的配置,解决多线程场景下,获取不到request上下文的问题
threadPoolExecutor.setTaskDecorator(new MyDecorator());
threadPoolExecutor.initialize();
return threadPoolExecutor;
当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略, rejectedExecutionHandler 字段用于配置拒绝策略,常用的拒绝策略如下:
- AbortPolicy:用于被拒绝任务的处理程序,它将抛出 RejectedExecutionException。
- CallerRunsPolicy:用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务。
- DiscardOldestPolicy:用于被拒绝任务的处理程序,它放弃最旧的未处理请求,然后重试 execute。
- DiscardPolicy:用于被拒绝任务的处理程序,默认情况下它将丢弃被拒绝的任务。
import org.slf4j.MDC;
import org.springframework.core.task.TaskDecorator;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import java.util.Map;
/**
* @author yangzhenyu
* @version 1.0
* @description:
* @date 2022/9/13 18:35
*/
public class MyDecorator implements TaskDecorator
@Override
public Runnable decorate(Runnable runnable)
RequestAttributes context = RequestContextHolder.currentRequestAttributes();
Map<String,String> previous = MDC.getCopyOfContextMap();
return () ->
try
RequestContextHolder.setRequestAttributes(context);
if (null != previous)
MDC.setContextMap(previous);
runnable.run();
finally
RequestContextHolder.resetRequestAttributes();
MDC.clear();
;
02::02 使用
我们这里用单元测试来进行测试。
注解式使用:
在使用多线程方法上标注@Async时表明调用的线程池
package com.yzy.task;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
/**
* @author yangzhenyu
* @version 1.0
* @description:
* @date 2022/9/13 17:11
*/
@Component
@Slf4j
public class Tast
//在使用多线程方法上标注@Async时表明调用的线程池
//注意:一定要在Spring的环境下
@Async("poolTaskExecutor")
public void testTast() throws InterruptedException
log.info("=========== hello ==============");
注意:一定要在Spring的环境下
测试:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ThymeleafDemo.class)
@Slf4j
public class TastTest
// 注入ThreadPoolTaskExecutor
@Resource
private Tast tast;
//注解式实现
@Test
public void ThreadTest_01() throws InterruptedException
log.info("测试开始>>>");
for (int i=0;i<10;i++)
tast.testTast();
log.info("测试结束>>>");
创建并执行线程方式:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ThymeleafDemo.class)
@Slf4j
public class TastTest
@Qualifier("poolTaskExecutor")
@Resource
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
//创建并执行线程方式
@Test
public void ThreadTest_02()
log.info("测试开始>>>");
MDC.put("yzy", "yangzhenyu");
for (int i=0;i<10;i++)
//lambda表达式
threadPoolTaskExecutor.execute(()->
System.out.printf("lambda-当前线程%s%n",Thread.currentThread().getName());
);
log.info("测试结束>>>");
以上是关于springBoot 的默认线程池-ThreadPoolTaskExecutor的主要内容,如果未能解决你的问题,请参考以下文章
springBoot 的默认线程池-ThreadPoolTaskExecutor
springBoot 的默认线程池-ThreadPoolTaskExecutor