springboot线程池的配置使用[通俗易懂]

springboot线程池的配置使用[通俗易懂]我们都知道,java中有ThreadPoolExecutor提供的线程池服务,非常好用。可以有效的解决了一些异步业务,提高系统性能。但是java中配置和使用线程池有点繁琐,而在springboot中,线程池的配置简直就是轻而易举。下面直接上干货。springboot中主要使用配置类来配置线程池@Async注解可以使用配置好的线程池下面我们来详细看一下配置和使用的过程1、配置线程池主要使用…

大家好,又见面了,我是你们的朋友全栈君。

我们都知道,java中有ThreadPoolExecutor提供的线程池服务,非常好用。可以有效的解决了一些异步业务,提高系统性能。但是java中配置和使用线程池有点繁琐,而在springboot中,线程池的配置简直就是轻而易举。下面直接上干货。
springboot中主要使用配置类来配置线程池
@Async注解可以使用配置好的线程池
其他的配置例如yml或者properties文件,按照springboot的正常配置就行,没什么特殊的。当然了,如果springboot不熟悉的,建议先去百度或者Google看一下springboot的入门教程。
下面我们来详细看一下配置和使用的过程
1、配置线程池
主要使用到 @Configuration @EnableAsync这两个注解,从字面上可以看出,前者是自定义配置类,后者是使能线程池。下面是我的一个配置类示例:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author zhaoxi
 * @date 2018/11/16 14:33
 * TODO:线程池的配置
 */
@Configuration
@EnableAsync
public class ExecutorConfig {

    private static final Logger logger = LoggerFactory.getLogger(ExecutorConfig.class);

    /**
     * TODO: 此方法名称为asyncPromiseExecutor,即在spring中注入了一个名字为asyncPromiseExecutor的bean
     * 方法名只要在项目中唯一性,可以适当任意取(最好遵循一定的规则)
     * 使用方法:在需要加入线程池的方法上增加注解@Async("asyncPromiseExecutor")就可以加入此线程池异步执行
     *
     * @return
     * @throws
     * @author zhaoxi
     * @time 2018/11/16 14:36
     * @params
     */
    @Bean
    public Executor asyncPromiseExecutor() {
        logger.info("start asyncPromiseExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(5);
        //配置最大线程数
        executor.setMaxPoolSize(10);
        //配置队列大小
        executor.setQueueCapacity(99999);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("async-promise-");
        /**
         * rejection-policy:当pool已经达到max size的时候,如何处理新任务
         * CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
         */
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化执行器
        executor.initialize();
        return executor;
    }
}

2、使用线程池
刚才我们在配置类定义了一个方法,并且使用了@Bean ,故而spring中注入了一个名字为asyncPromiseExecutor的bean。故而我们只需要去某个实现类的方法上加上springboot提供的@Async注解即可;注解中指明要加入的线程池,例如 @Async(“asyncPromiseExecutor”)
示例:
controller层

    @ApiOperation("分享游戏")
    @PostMapping("/share/xxx/game")
    public PaixiResult promiseShareGame(String token) {
        if (Util.isEmpty(token)) {
            return ResponseUtils.build(401, "请传入token");
        }
        log.info("开始判断是否首次分享游戏");
        promiseService.promiseShareGame(token);
        log.info("成功提交到线程池,本请求可以返回了");
        return ResponseUtils.SUCCESS(token);
    }

service层
接口

/**
 * TODO: 分享游戏
 * 丢到线程池里面异步执行
 *
 * @return
 * @throws
 * @author zhaoxi
 * @time 2018/11/16 14:27
 * @params
 */
void promiseShareGame(String token);

实现

    @Override
    @Async("asyncPromiseExecutor") //此处方法实现被加入到线程池中执行。当前的方法立刻返回,上级调用即可结束
    public void promiseShareGame(String token) {
        //获取userId
        String userId = userFeign.getUserIdByToken(token);
        if (Util.isEmpty(userId)) {
            return;
        }
        /**
         * 耗时试验
         */
        log.info("开始耗时等待");
        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("耗时等待结束,线程结束");
    }

注意:
设置加入到线程池的方法不应该有返回值,虽然定义为有返回值程序执行无错误,但是定义为线程的方法,上级调用者无需等待处理结果,如果调用者强行等待返回结果,此异步设置将会没有意义,系统仍然会按照同步的逻辑处理。读者可以自己动手试验一下!
3、知识总结
corePoolSize,maximumPoolSize,workQueue之间关系。
1).当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2).当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
3).当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
4).当提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
5).当线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
6).当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148506.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 对象转JSON首字母大写[通俗易懂]

    对象转JSON首字母大写[通俗易懂]最近在做一个第三方接口,接口给的数据类型如下请求报文如下{“A0144″:”12141256″,”AB6AM”:”中国银行支行”,”STATUS”:1}一般按照对象转JSON会使首字母小写,与接口文档不相符,因此需要转为大写,在字段名称前加@JSONField(name=””)注释即可如下:packagecn.com.cis.acic.util.personHr.vo.request;importcom.alibaba.fastjson.annotation.JS…

    2025年12月10日
    6
  • discuz找不到php.ini,解决Discuz安装时报错“该函数需要 php.ini 中 allow_url_fopen 选项开启…” | Linux玩家…

    discuz找不到php.ini,解决Discuz安装时报错“该函数需要 php.ini 中 allow_url_fopen 选项开启…” | Linux玩家…开启php的fsockopen函数——解决DZ论坛安装问题“该函数需要php.ini中allow_url_fopen选项开启。请联系空间商,确定开启了此项功能在安装dz论坛时遇到因为fsockopen()函数问题无法进入下一步,安装错误显示“该函数需要php.ini中allow_url_fopen选项开启。请联系空间商,确定开启了此项功能”,经过分析,总结了3个解决这个问题的办…

    2022年7月21日
    14
  • WinSCP连接linux系统root登录时拒绝访问解决办法

    WinSCP连接linux系统root登录时拒绝访问解决办法1.编辑/etc/ssh/sshd_config文件:sudovi/etc/ssh/sshd_config将PermitRootLogin的值改成yes将PermitEmptyPassword的值改成no保存退出2.重启ssh:sudoservicesshrestart3.即可在WinSCP用root用户登陆转自https://blog.c…

    2025年12月13日
    5
  • 洛谷头像上传方法

    洛谷头像上传方法洛谷头像很多用户反馈经常上传失败在这边提供一个方法 提示上传成功以后按 Ctrl F5 即可成功更改头像点这里前往洛谷

    2025年10月9日
    7
  • 关于matlab GUI重命名的问题。「建议收藏」

    关于matlab GUI重命名的问题。「建议收藏」我们在用matlab开发GUI的时候,有时往往觉得GUI名字不好,想要换一个GUI的名字。很多人的做法是:修改fig和m文件名。但是只这样修改后,再运行程序时,发现出现了好多错误,程序根本无法运行。这时的你发现,噢!原来在m文件里面还需要修改,你需要手动将.m中的所有函数的前边部分重新修改进行替换,但是这样修改太繁琐,如果是一个简单的GUI还行,要是复杂的,改得你怀疑人生,还容易出错,出错后都难

    2022年5月29日
    58
  • JQuery安装与下载教程(efficiency)

    JQuery安装与下载教程(efficiency)一.认识(1)jQuery文件有两个常用版本:一个是1.x版本,另一个是3.x版本。3.x版本是目前的最新版本,与1.x版本有着相同的API。1.x版本兼容IE6、IE7和IE8,而3.x版本不兼容IE6、IE7和IE8。在实际开发中,我们建议使用1.x版本,而不是3.x版本,原因有两个:1.现在很多网站还是要考虑兼容IE6~IE8;2.大多数jQuery插件不支持3.x版本,只支持1.x版本。不管是1.x版本,还是3.x版本

    2022年6月5日
    30

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号