当前位置: 首页 > news >正文

springBoot 的默认线程池-ThreadPoolTaskExecutor

文章目录

  • 前言
    • springBoot 的默认线程池
      • 01 ThreadPoolTaskExecutor是什么?
      • 02 实战
        • 02::01 配置
        • 02::02 使用

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


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("测试结束>>>");

    }
}

在这里插入图片描述

相关文章:

  • 暑期结束为你的新学期立下Flag吧
  • 大数字符串加法
  • ROS1云课→28机器人代价地图配置
  • 设计新鲜事(News Feed)系统
  • 【气动学】基于matlab GUI弹道问题(含初始角度、速度、空气阻力、水平风)【含Matlab源码 2117期】
  • 力扣leetcode 1619. 删除某些元素后的数组均值
  • 嵌入式入门-交叉编译、bootloader、kernel、根文件系统关系
  • Google Earth Engine(GEE)——快速建立一个10km的格网
  • 关于微信学习的网站
  • 微服务项目:尚融宝(38)(核心业务流程:申请借款额度(1))
  • 八股文复习
  • quartz学习笔记
  • [项目管理-28]:四象限法与任务的时间优先级管理
  • [数据分析] 矩形树图(Treemap)
  • 35了,我该何去何从
  • 【技术性】Search知识
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Consul Config 使用Git做版本控制的实现
  • Django 博客开发教程 8 - 博客文章详情页
  • Docker: 容器互访的三种方式
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • ECMAScript入门(七)--Module语法
  • github从入门到放弃(1)
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JAVA多线程机制解析-volatilesynchronized
  • JS字符串转数字方法总结
  • k8s 面向应用开发者的基础命令
  • mysql 数据库四种事务隔离级别
  • Promise面试题,控制异步流程
  • React-Native - 收藏集 - 掘金
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 分布式事物理论与实践
  • 关于for循环的简单归纳
  • 猴子数据域名防封接口降低小说被封的风险
  • 每天10道Java面试题,跟我走,offer有!
  • 前端路由实现-history
  • 前端设计模式
  • 我建了一个叫Hello World的项目
  • 小程序开发之路(一)
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 转载:[译] 内容加速黑科技趣谈
  • raise 与 raise ... from 的区别
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • #{}和${}的区别是什么 -- java面试
  • #传输# #传输数据判断#
  • $(selector).each()和$.each()的区别
  • (1)(1.13) SiK无线电高级配置(五)
  • (175)FPGA门控时钟技术
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (floyd+补集) poj 3275
  • (ibm)Java 语言的 XPath API
  • (windows2012共享文件夹和防火墙设置