千家信息网

如何使用Springboot线程池

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,今天就跟大家聊聊有关如何使用Springboot线程池,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。创建springboot工程用Intell
千家信息网最后更新 2026年11月01日如何使用Springboot线程池

今天就跟大家聊聊有关如何使用Springboot线程池,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

创建springboot工程

用IntelliJ IDEA创建一个springboot的web工程threadpooldemoserver,pom.xml内容如下:

    4.0.0    com.vincent    threadpooldemoserver    1.0-SNAPSHOT            UTF-8        1.8        1.8                                            org.springframework.boot                spring-boot-dependencies                2.1.4.RELEASE                import                pom                                                org.springframework.boot            spring-boot-starter-web                            org.projectlombok            lombok            1.18.6                                                    org.springframework.boot                spring-boot-maven-plugin                2.1.4.RELEASE                                    cn.ac.iie.App                                                                                                        repackage                                                                                                    org.apache.maven.plugins                maven-surefire-plugin                                    true                                        

创建Service层的接口和实现

创建一个service层的接口AsyncService,如下:

public interface AsyncService {    /**     * 执行异步任务     */    void executeAsync();}

对应的AsyncServiceImpl,实现如下:

@Service@Slf4jpublic class AsyncServiceImpl implements AsyncService {    @Override    public void executeAsync() {        log.info("start executeAsync");        try{            Thread.sleep(1000);        }catch(Exception e){            e.printStackTrace();        }        log.info("end executeAsync");    }}

这个方法做的事情很简单:sleep了一秒钟;

创建controller

创建一个controller为Hello,里面定义一个http接口,做的事情是调用Service层的服务,如下:

@RestController@Slf4jpublic class Hello {    @Autowired    private AsyncService asyncService;    @RequestMapping("/")    public String submit() {        log.info("start submit");        //调用service层的任务        asyncService.executeAsync();        log.info("end submit");        return "success";    }}

至此,我们已经做好了一个http请求的服务,里面做的事情其实是同步的,接下来我们就开始配置springboot的线程池服务,将service层做的事情都提交到线程池中去处理;

springboot的线程池配置

创建一个配置类ExecutorConfig,用来定义如何创建一个ThreadPoolTaskExecutor,要使用@Configuration和@EnableAsync这两个注解,表示这是个配置类,并且是线程池的配置类,如下所示:

@Configuration@EnableAsync@Slf4jpublic class ExecutorConfig {    @Bean    public Executor asyncServiceExecutor() {        log.info("start asyncServiceExecutor");        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();        //配置核心线程数        executor.setCorePoolSize(5);        //配置最大线程数        executor.setMaxPoolSize(5);        //配置队列大小        executor.setQueueCapacity(99999);        //配置线程池中的线程的名称前缀        executor.setThreadNamePrefix("async-service-");        // rejection-policy:当pool已经达到max size的时候,如何处理新任务        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());        //执行初始化        executor.initialize();        return executor;    }}

注意,上面的方法名称为asyncServiceExecutor,稍后马上用到;

将Service层的服务异步化

打开AsyncServiceImpl.java,在executeAsync方法上增加注解@Async("asyncServiceExecutor"),asyncServiceExecutor是前面ExecutorConfig.java中的方法名,表明executeAsync方法进入的线程池是asyncServiceExecutor方法创建的,如下:

@Service@Slf4jpublic class AsyncServiceImpl implements AsyncService {    @Override    @Async("asyncServiceExecutor")    public void executeAsync() {        log.info("start executeAsync");        try{            Thread.sleep(1000);        }catch(Exception e){            e.printStackTrace();        }        log.info("end executeAsync");    }}

验证效果

  1. 将这个springboot运行起来(pom.xml所在文件夹下执行mvn spring-boot:run);

  2. 在浏览器输入:http://localhost:8080;

  3. 在浏览器用F5按钮快速多刷新几次;

  4. 在springboot的控制台看见日志如下:

2019-08-12 15:23:00.320  INFO 5848 --- [nio-8080-exec-2] cn.ac.iie.controller.Hello               : start submit2019-08-12 15:23:00.327  INFO 5848 --- [nio-8080-exec-2] cn.ac.iie.controller.Hello               : end submit2019-08-12 15:23:00.327  INFO 5848 --- [async-service-1] cn.ac.iie.service.impl.AsyncServiceImpl  : start executeAsync2019-08-12 15:23:01.329  INFO 5848 --- [async-service-1] cn.ac.iie.service.impl.AsyncServiceImpl  : end executeAsync2019-08-12 15:24:17.449  INFO 5848 --- [nio-8080-exec-5] cn.ac.iie.controller.Hello               : start submit2019-08-12 15:24:17.450  INFO 5848 --- [nio-8080-exec-5] cn.ac.iie.controller.Hello               : end submit2019-08-12 15:24:17.450  INFO 5848 --- [async-service-2] cn.ac.iie.service.impl.AsyncServiceImpl  : start executeAsync2019-08-12 15:24:18.125  INFO 5848 --- [nio-8080-exec-6] cn.ac.iie.controller.Hello               : start submit2019-08-12 15:24:18.126  INFO 5848 --- [nio-8080-exec-6] cn.ac.iie.controller.Hello               : end submit2019-08-12 15:24:18.128  INFO 5848 --- [async-service-3] cn.ac.iie.service.impl.AsyncServiceImpl  : start executeAsync2019-08-12 15:24:18.451  INFO 5848 --- [async-service-2] cn.ac.iie.service.impl.AsyncServiceImpl  : end executeAsync2019-08-12 15:24:18.685  INFO 5848 --- [nio-8080-exec-7] cn.ac.iie.controller.Hello               : start submit2019-08-12 15:24:18.688  INFO 5848 --- [nio-8080-exec-7] cn.ac.iie.controller.Hello               : end submit2019-08-12 15:24:18.703  INFO 5848 --- [async-service-4] cn.ac.iie.service.impl.AsyncServiceImpl  : start executeAsync2019-08-12 15:24:19.130  INFO 5848 --- [async-service-3] cn.ac.iie.service.impl.AsyncServiceImpl  : end executeAsync2019-08-12 15:24:19.704  INFO 5848 --- [async-service-4] cn.ac.iie.service.impl.AsyncServiceImpl  : end executeAsync

如上日志所示,我们可以看到controller的执行线程是"nio-8080-exec-5",这是tomcat的执行线程,而service层的日志显示线程名为"async-service-1",显然已经在我们配置的线程池中执行了,并且每次请求中,controller的起始和结束日志都是连续打印的,表明每次请求都快速响应了,而耗时的操作都留给线程池中的线程去异步执行;

扩展ThreadPoolTaskExecutor

虽然我们已经用上了线程池,但是还不清楚线程池当时的情况,有多少线程在执行,多少在队列中等待呢?这里我创建了一个ThreadPoolTaskExecutor的子类,在每次提交线程的时候都会将当前线程池的运行状况打印出来,代码如下:

@Slf4jpublic class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {    private void showThreadPoolInfo(String prefix){        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();        if(null==threadPoolExecutor){            return;        }        log.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}], queueSize [{}]",                this.getThreadNamePrefix(),                prefix,                threadPoolExecutor.getTaskCount(),                threadPoolExecutor.getCompletedTaskCount(),                threadPoolExecutor.getActiveCount(),                threadPoolExecutor.getQueue().size());    }    @Override    public void execute(Runnable task) {        showThreadPoolInfo("1. do execute");        super.execute(task);    }    @Override    public void execute(Runnable task, long startTimeout) {        showThreadPoolInfo("2. do execute");        super.execute(task, startTimeout);    }    @Override    public Future submit(Runnable task) {        showThreadPoolInfo("1. do submit");        return super.submit(task);    }    @Override    public  Future submit(Callable task) {        showThreadPoolInfo("2. do submit");        return super.submit(task);    }    @Override    public ListenableFuture submitListenable(Runnable task) {        showThreadPoolInfo("1. do submitListenable");        return super.submitListenable(task);    }    @Override    public  ListenableFuture submitListenable(Callable task) {        showThreadPoolInfo("2. do submitListenable");        return super.submitListenable(task);    }}

如上所示,showThreadPoolInfo方法中将任务总数、已完成数、活跃线程数,队列大小都打印出来了,然后Override了父类的execute、submit等方法,在里面调用showThreadPoolInfo方法,这样每次有任务被提交到线程池的时候,都会将当前线程池的基本情况打印到日志中;

修改ExecutorConfig.java的asyncServiceExecutor方法,将ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor()改为ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor(),如下所示:

    @Bean    public Executor asyncServiceExecutor() {        log.info("start asyncServiceExecutor");        ThreadPoolTaskExecutor executor = new VisiableThreadPoolTaskExecutor();        //配置核心线程数        executor.setCorePoolSize(5);        //配置最大线程数        executor.setMaxPoolSize(5);        //配置队列大小        executor.setQueueCapacity(99999);        //配置线程池中的线程的名称前缀        executor.setThreadNamePrefix("async-service-");        // rejection-policy:当pool已经达到max size的时候,如何处理新任务        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());        //执行初始化        executor.initialize();        return executor;    }

修改hello.java,方便查看线程池结果:

    @RequestMapping("/")    public Object submit() {        log.info("start submit");        //调用service层的任务        asyncService.executeAsync();        log.info("end submit");        JSONObject jsonObject = new JSONObject();        ThreadPoolExecutor threadPoolExecutor = visiableThreadPoolTaskExecutor.getThreadPoolExecutor();        jsonObject.put("ThreadNamePrefix", visiableThreadPoolTaskExecutor.getThreadNamePrefix());        jsonObject.put("TaskCount", threadPoolExecutor.getTaskCount());        jsonObject.put("completedTaskCount", threadPoolExecutor.getCompletedTaskCount());        jsonObject.put("activeCount", threadPoolExecutor.getActiveCount());        jsonObject.put("queueSize", threadPoolExecutor.getQueue().size());        return jsonObject;    }

再次启动该工程,再浏览器反复刷新http://localhost:8080,看到的日志如下:

{    "activeCount": 2,    "queueSize": 1,    "TaskCount": 26,    "completedTaskCount": 23,    "ThreadNamePrefix": "async-service-"}

看完上述内容,你们对如何使用Springboot线程池有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。

线程 配置 方法 任务 日志 事情 内容 时候 队列 服务 名称 大小 工程 所在 接口 浏览 最大 前缀 如上 情况 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 亿人帮互联网科技有限公司 互联网科技巨头监管 没上市的科技互联网公司 中资互联网科技 青岛互联网科技公司 互联网科技的英文 壹账通互联网科技 互联网公司会议桌创意科技软装饰 卫星互联网科技股票 团飞科技与伯堂互联网服务平台 世界互联网科技公司市值排名 华夏互联网科技业 互联网与医疗科技 链环科技传统企业怎么转型互联网 内蒙古九一互联网科技 互联网公司高科技产品 宁波跨境商互联网科技有限公司 上海同邻互联网科技有限公司规模 昆明中奇联合互联网科技 珠海东科互联网科技有限公司 上海挚品互联网科技有限公司 互联网科技巨头监管 互联网巨头科技公司 互联网医疗科技 万达互联网科技 哈尔滨新华互联网科技学院 温州喔噻互联网科技有限公司 华夏恒生互联网科技013171 互联网公司黑科技创始人 上海乐五互联网科技有限公司
0