Springboot 使用 Async 执行异步任务

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/u010979642/article/details/102456288

使用 Async 执行异步任务

@SpringBootApplication
@EnableAsync
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

声明异步任务

@Component
@Slf4j
public class AsyncTask {
    /**
     * 通知计数
     * */
    @Async
    public void notifyCount() {
        log.info("执行异步任务-通知计数开始");

        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("执行异步任务-通知计数结束");
    }

    /**
     * 通知邮件-带返回值
     * */
    @Async
    public Future<String> notifyEmail() {
        log.info("执行异步任务-通知邮件开始");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("执行异步任务-通知邮件结束");
        return new AsyncResult<>("send email success");
    }
}

执行异步任务

@RestController
@RequestMapping("")
@Slf4j
public class AnalysController {
	@Autowired
	private AsyncTask asyncTask;

	@RequestMapping(value = "index", method = RequestMethod.GET)
    public XloResponse index() throws Exception {
		// 通知计数
        asyncTask.notifyCount();
        // 通知邮件
        Future<String> stringFuture = asyncTask.notifyEmail();
        
        // TODO 业务逻辑处理
        
        // 阻塞获取通知邮件的结果
        log.info(stringFuture.get());
	}
}

自定义执行异步任务的线程池信息

声明式

spring.task.execution.pool.core-size=10
spring.task.execution.pool.max-size=50
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.queue-capacity=2
spring.task.execution.thread-name-prefix=MyTask-

编程式

@Slf4j
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

    /**
     * 处理异步方法调用时要使用的实例 <br /><br />
     *
     *
     * 拒绝策略常用有有这四种
     * <ul>
     *     <li>
     *         <b>ThreadPoolExecutor.AbortPolicy: </b>丢弃任务并抛出RejectedExecutionException异常(默认)
     *     </li>
     *     <li>
     *         <b>ThreadPoolExecutor.DiscardPolic: </b>丢弃任务,但是不抛出异常
     *     </li>
     *     <li>
     *         <b>ThreadPoolExecutor.DiscardOldestPolicy: </b>丢弃队列最前面的任务,然后重新尝试执行任务
     *     </li>
     *     <li>
     *         <b>ThreadPoolExecutor.CallerRunsPolic: </b>由调用线程处理该任务
     *     </li>
     * </ul>
     * */
    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(10);
        // 最大线程数
        executor.setMaxPoolSize(60);
        // 线程最大空闲时间
        executor.setKeepAliveSeconds(60);
        // 队列大小
        executor.setQueueCapacity(10);
        // 指定用于新创建的线程名称的前缀
        executor.setThreadNamePrefix("MyExecutor-");
        // 拒绝策略
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        
		// 等待任务在关机时完成--表明等待所有线程执行完
//        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时间(默认为0,此时立即停止), 并在等待xx秒后强制停止
//        executor.setAwaitTerminationSeconds(60 * 5);

		// 初始化
        executor.initialize();
        return executor;
    }

    /**
     * 对void方法抛出的异常处理方法
     * */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    	// 使用自定义异常处理类 lambda方式
//        return (throwable, method, objects) -> log.info("抛异常啦~~~throwable={},method={},params={}", throwable, method, objects);
		// 使用自定义异常处理类
//        return new MyAsyncExceptionHandler();
		// 使用系统自带异常处理类
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

编程式 + 声明式

spring.async.executor.pool.core-size=10
spring.async.executor.pool.max-size=60
spring.async.executor.pool.keep-alive-seconds=60
spring.async.executor.pool.queue-capacity=10
spring.async.executor.pool.thread-name-prefix=XloTask-
@Slf4j
@EnableAsync
@Configuration
@ConfigurationProperties(prefix="spring.async.executor.pool")
@Data
public class AsyncConfig implements AsyncConfigurer {

    private Integer coreSize;
    private Integer maxSize;
    private Integer keepAliveSeconds;
    private Integer queueCapacity;
    private String threadNamePrefix;

    /**
     * 处理异步方法调用时要使用的实例
     * */
    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(coreSize);
        // 最大线程数
        executor.setMaxPoolSize(maxSize);
        // 线程最大空闲时间
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 队列大小
        executor.setQueueCapacity(queueCapacity);
        // 指定用于新创建的线程名称的前缀
        executor.setThreadNamePrefix(threadNamePrefix);
        executor.initialize();
        return executor;
    }

    /**
     * Async无返回方法的异常处理方法
     * */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> log.info("抛异常啦~~~throwable={},method={},params={}", throwable, method, objects);
    }

}

自定义异常处理类

/**
 * <p>
 *     自定义异常处理类
 * </p>
 *
 * @author Answer.AI.L
 * @version 1.0
 * @date 2019-10-09
 */
@Slf4j
public class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... params) {
        log.info("Exception message - " + throwable.getMessage());
        log.info("Method name - " + method.getName());
        for (Object param: params) {
            log.info("Parameter value - " + param);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/u010979642/article/details/102456288