Springboot 配置异步线程池

353 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

异步在项目中用到的很多

为什么要配置异步线程池,默认的线程池并不会去复用线程,所以我们需要配置线程池参数从而使得异步任务更高效的执行。

下面我们就来配置一下

具体的线程池参数 大家可以看看我之前写的另一篇 springboot CompletableFuture异步线程池 这里就不多讲啦..........😁

@Configuration
@EnableAsync
public class ThreadPoolConfig
{
    // 核心线程池大小
    private int corePoolSize = 5;

    // 最大可创建的线程数
    private int maxPoolSize = 10;

    // 队列最大长度
    private int queueCapacity = 20;

    // 线程池维护线程所允许的空闲时间
    private int keepAliveSeconds = 300;

        @Bean(name = "threadPoolExecutor")
        public Executor  threadPoolExecutor(){
        ThreadPoolTaskExecutor  executor =new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);//核心池大小
        executor.setMaxPoolSize(maxPoolSize);//最大线程数
        executor.setQueueCapacity(queueCapacity);//队列长度  不设置为无边界
        executor.setKeepAliveSeconds(keepAliveSeconds);//线程空闲时间
         executor.setThreadNamePrefix("bugVip-asyn");//线程前缀名称
         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());//配置拒绝
         executor.initialize();
        return executor;
    }


}

项目中使用

@Async("threadPoolExecutor")
public  void loginLogSet(String username, String description, Integer logType, Integer runType, Integer whereType, String message) throws InterruptedException {
}

控制台打印

image.png @Async("threadPoolExecutor")里面指定使用的线程池,因为我们可以配置多个线程池前提是你的硬件跟的上哈哈,一般就是两个池子核心业务和一般业务(日志记录呀等等)。

还可以使用Aop 做一个获取线程池子的执行状态的注解

注解 @ThreadPoolStatus这里就不多少怎么创建了

@RequestMapping("info")
@ThreadPoolStatus("info-------------------------------------->")
public R info(HttpServletRequest request){
    String tokeninfo = tokenManager.getUserToken(request.getHeader(header));
    OnlineUserInfo principal = redisTemplate.getCacheObject(RedisConstant.ONLINE_BOSS_INFO + tokeninfo);
    SysUser sysUser = principal.getSysUser();
    return R.ok().data("user",sysUser);
}

Aop的代码

@Slf4j
@Aspect
@Component
public class TheadPoolLogAop {
    @Resource(name = "threadPoolExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Pointcut("@annotation(com.xk.bugvip.boss.log.ThreadPoolStatus)")
    public void threadPoolStatus(){}

    private static HashMap<String, Class> map = new HashMap<String, Class>() {
        {
            put("java.lang.Integer", int.class);
            put("java.lang.Double", double.class);
            put("java.lang.Float", float.class);
            put("java.lang.Long", long.class);
            put("java.lang.Short", short.class);
            put("java.lang.Boolean", boolean.class);
            put("java.lang.Char", char.class);
            put("javax.servlet.http.HttpServletRequest", HttpServletRequest.class);
        }
    };
    @Around("threadPoolStatus()")
    public Object threadPoolDoing(ProceedingJoinPoint point) throws Throwable {
        Object target = point.getTarget();
        Class<?> aClass = target.getClass();
        String name = aClass.getName();
        String methodName = point.getSignature().getName();
        Object[] args = point.getArgs();
        Class<?>[] classes = new Class[args.length];
        for (int k = 0; k < args.length; k++) {
            if (!args[k].getClass().isPrimitive()) {
                //获取的是封装类型而不是基础类型
                String result = args[k].getClass().getName();
                Class s = map.get(result);
                classes[k] = s == null ? args[k].getClass() : s;
            }
        }
        //获取指定的方法,第二个参数可以不传,但是为了防止有重载的现象,还是需要传入参数的类型
        Class<?> aClass1 = Class.forName(name);
        try {
            MethodSignature methodSignature = (MethodSignature)point.getSignature();
            ThreadPoolStatus annotation = methodSignature.getMethod().getAnnotation(ThreadPoolStatus.class);
            showThreadPoolInfo(annotation.value());
            return point.proceed();

        }catch (Exception e){
            log.info(e.getMessage());
        }
        return null;
    }

    private void showThreadPoolInfo(String prefix){
        ThreadPoolExecutor threadPoolExecutor = threadPoolTaskExecutor.getThreadPoolExecutor();
        if(null==threadPoolExecutor){
            return;
        }
        log.info("{}, {},taskCount [{}], completedTaskCount [{}], activeCount [{}],PoolSize[{}],LargestPoolSize[{}], queueSize [{}]",
                threadPoolTaskExecutor.getThreadNamePrefix(),
                prefix,
                threadPoolExecutor.getTaskCount(),//线程需要执行的任务个数。
                threadPoolExecutor.getCompletedTaskCount(),//线程池在运行过程中已完成的任务数。
                threadPoolExecutor.getActiveCount(),//获取活动的线程的数量。
                threadPoolExecutor.getPoolSize(),//当前相乘数量
                threadPoolExecutor.getLargestPoolSize(),//线程池曾经创建过的最大线程数量。
                threadPoolExecutor.getQueue().size());//任务队列中任务数量
    }
}

输出结果

image.png 这个功能可能有点鸡肋,但是也是可以用的。感兴趣的可以去试试........

实践是检验真理的唯一方法! 明天见🥰🥰🥰