前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot 线程池

Springboot 线程池

作者头像
收心
发布2022-01-19 11:09:33
5490
发布2022-01-19 11:09:33
举报
文章被收录于专栏:Java实战博客

传统的请求,都是单线程的!但是线程名不一样!很多时候就会造成堵塞!

代码语言:javascript
复制
@Service
public class AsyncServiceImpl implements AsyncService {

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

    @Override
    public void executeAsync() {
        logger.info("Start executeAsync");
        try {
            Thread.sleep(10000);
            logger.info("当前线程名:"+Thread.currentThread().getName());
        } catch (Exception e) {
            logger.error("executeAsync exception");
        }
        logger.info("end executeAsync");
    }
}

同时发送2个请求,结果如下

由上图得知,2个请求同时进来,线程3执行时,线程9就是阻塞状态!当线程3执行完毕后,线程9才会开始执行!可想而知,这种串行机制,会非常耽误请求响应的时间!所以我们采用并行机制,多线程来实现!

Springboot整合 多线程 正文

下面代码包含了线程池的4种 拒绝策略 RejectedExecutor 下面代码注释有说明

代码语言:javascript
复制
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 : zanglikun
 * @date : 2021/12/30 9:39
 * @Version: 1.0
 * @Desc : 线程池的配置
 */
@Configuration
@EnableAsync
public class ExecutorConfig {

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


    // 定义一个线程池 方法名很重要!其他方法使用线程池必须指定此方法!
    @Bean
    public Executor asyncServiceExecutor(){
        logger.info("Start AsyncServiceExecutor");
        ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor();
        // 配置设定核心线程数: 最小存在的线程数,如果当前线程小于队列数,依旧会创建线程!使得总线程数 >= 核心线程数
        threadPoolExecutor.setCorePoolSize(5);
        // 配置最大线程数
        threadPoolExecutor.setMaxPoolSize(5);
        // 配置非核心线程空闲线程存活时间 单位秒 默认是60秒
        threadPoolExecutor.setKeepAliveSeconds(60);
        // 允许运行线程数量为 0   这个一般不设置
        //threadPoolExecutor.setAllowCoreThreadTimeOut(true);
        // 配置待执行任务队列大小 默认是(Interger.MaxValue)
        threadPoolExecutor.setQueueCapacity(10);
        // 配置线程池中线程的前缀名
        threadPoolExecutor.setThreadNamePrefix("Async-service-");

        // 配置阻塞队列满后执行拒绝策略。
        /*
         AbortPolicy 这是默认策略。队列满了,是直接抛出 RejectedExecutionException 异常。
         CallerRunsPolicy 是阻塞新任务进入队列。如果当线程池的线程有空余,才回去读取队列任务执行,才会将阻塞任务加入队列。
         DiscardOldestPolicy 是丢弃队列中靠最前的任务。 如果队列有A、B、C 的3个阻塞,此时没有新的线程空闲,突然来了D线程,A线程就会被D代替。此时队列的排序是 B、C、D
         DiscardPolicy 是队列满了,直接丢弃新的任务。
         */
        threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolExecutor.initialize();
        logger.info("End AsyncServiceRxecutor");
        return threadPoolExecutor;
    }
}

接下来 在ServiceImpl 的具体方法加入 注解@Async(”线程池的方法“)

代码语言:javascript
复制
    @Override
    @Async("asyncServiceExecutor")
    //@Async("这里填写的是你线程池的方法名,此处如果不写,会使用Spring默认的线程池")
    public void executeAsync() {
        logger.info("Start executeAsync");
        try {
            Thread.sleep(10000);
            logger.info("当前线程名:"+Thread.currentThread().getName());
        } catch (Exception e) {
            logger.error("executeAsync exception");
        }
        logger.info("end executeAsync");
    }

结果是:

代码语言:javascript
复制
2021-12-30 18:47:22.597  INFO 15728 --- [Async-service-1] c.x.z.s.serviceImpl.AsyncServiceImpl     : Start executeAsync
2021-12-30 18:47:22.841  INFO 15728 --- [Async-service-2] c.x.z.s.serviceImpl.AsyncServiceImpl     : Start executeAsync
2021-12-30 18:47:32.598  INFO 15728 --- [Async-service-1] c.x.z.s.serviceImpl.AsyncServiceImpl     : 当前线程名:Async-service-1
2021-12-30 18:47:32.598  INFO 15728 --- [Async-service-1] c.x.z.s.serviceImpl.AsyncServiceImpl     : end executeAsync
2021-12-30 18:47:32.842  INFO 15728 --- [Async-service-2] c.x.z.s.serviceImpl.AsyncServiceImpl     : 当前线程名:Async-service-2
2021-12-30 18:47:32.842  INFO 15728 --- [Async-service-2] c.x.z.s.serviceImpl.AsyncServiceImpl     : end executeAsync

Async-service-1 执行的时候 与 Async-service-2 执行时并行处理,不冲突、不阻塞!这就是线程池的异步执行!

完结!

特殊说明:以上文章,均是我实际操作,写出来的笔记资料,不会盗用别人文章!烦请各位,请勿直接盗用!转载记得标注来源!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 同时发送2个请求,结果如下
  • Springboot整合 多线程 正文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档