springboot异步多线程的实现

1、配置线程池相关参数

package com.xxx.test.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@Slf4j
@Configuration
@EnableAsync(proxyTargetClass = true)
public class AsyncConfig implements AsyncConfigurer {

    @Bean("asyncExecutor")
    public Executor asyncExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(Integer.MAX_VALUE);
        executor.setThreadNamePrefix("common-async-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    /**
     * 只能捕获无返回值的异步方法,有返回值的被主线程处理
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new CustomAsyncExceptionHandler();
    }


    /***
     * 处理异步方法中未捕获的异常
     */
    class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
            log.info("Exception message - {}", throwable.getMessage());
            log.info("Method name - {}", method.getName());
            log.info("Parameter values - {}", Arrays.toString(obj));
            if (throwable instanceof Exception) {
                Exception exception = (Exception) throwable;
                log.info("exception:{}", exception.getMessage());
            }
            throwable.printStackTrace();
        }
    }

}

2、编写异步服务

package com.xxx.xxx.service.impl;


import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.concurrent.Future;

@Slf4j
@Service
public class AsyncService {

    @Async("asyncExecutor")
    public void task1() throws Exception {
        log.info("task1开始执行");
        Thread.sleep(3000);
        log.info("task1执行结束");
        throw new RuntimeException("出现异常");
    }

    //todo 只能捕获无返回值的异步方法,有返回值的被主线程处理,还是要在主线程判断代码
    @Async("asyncExecutor")
    public Future<String> task2() throws Exception {
        log.info("task2开始执行");
        Thread.sleep(3000);
        log.info("task2执行结束");
        throw new RuntimeException("出现异常");
        // return new AsyncResult<String>("task2 success");
    }


    @Async("asyncExecutor")
    public Future<Integer> task3(Integer num) throws Exception {
        log.info("task3开始执行,num:{}", num);
        //Thread.sleep(3000);
        log.info("task3执行结束,num:{}", num);
        return new AsyncResult<Integer>(num);
    }


    @Async("asyncExecutor")
    public Future<String> task4() throws Exception {
        log.info("task4开始执行");
        Thread.sleep(3000);
        log.info("task4执行结束");
        return new AsyncResult<String>("task4 success");
    }

}

3、controller层服务调用

 @RequestMapping(value = "/getTest", method = RequestMethod.GET)
    public BasicResult getTest(Integer num) throws Exception {
        BasicResult<String> basicResult = new BasicResult<>();
        log.info("{} 接受到请求:num={}", Thread.currentThread().getName(), num);
        //TimeUnit.HOURS.sleep(1);
        asyncService.task1();
        asyncService.task2();
        Future<Integer> integerFuture = asyncService.task3(num);
        basicResult.setSingleResult(integerFuture.get().toString());
        return basicResult;
    }

4、如果启用异步线程池,需要在启动类加上  @EnableAsync(proxyTargetClass = true) 注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值