spring异步执行方法线程池的配置

有注解和xml两种方式,我这里只大概记录一下注解方式,趋势=-=

首先新建一个配置类,必须被spring管理,这里就不多说了…

import com.google.common.util.concurrent.ThreadFactoryBuilder;
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.ThreadPoolTaskScheduler;

import java.lang.reflect.Method;
import java.util.concurrent.*;

/**
 * Created by rdd on 2019/2/11.
 */
@Configuration//配置类
@Slf4j//日志
@EnableAsync//开启注解
//可以继承或者实现
//public class AsyncServiceConfig extends AsyncConfigurerSupport {
public class AsyncServiceConfig implements AsyncConfigurer {

    /**
     * 可以建多个线程池,然后使用@Async(value = "asyOneExecutor")可以指定不同线程池
     * 根据不同线程池的主要使用方式去选择对应的线程池
     * 不指定则使用getAsyncExecutor方法返回的线程池
     * @return
     */
    @Bean
    public ThreadPoolTaskScheduler asyOneExecutor() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(20);
        scheduler.setThreadNamePrefix("asy1-");
        scheduler.setAwaitTerminationSeconds(60);
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        return scheduler;
    }

    @Bean
    public ThreadPoolExecutor asyTwoExecutor() {
        //创建一个简单的线程池
//        ExecutorService executorService = Executors.newSingleThreadExecutor();

        //自定义个数线程池
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setDaemon(true).build();
        ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 50, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory);
        return pool;
    }

    @Override
    public Executor getAsyncExecutor() {
        Executor executor = this.asyOneExecutor();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        //异常捕捉
        return new AsyncServiceConfig.SpringAsyncExceptionHandler();
    }

    class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
            // 错误日志
            log.error("Exception occurs in async method", throwable.getMessage());
        }
    }
}

执行效果.
在这里插入图片描述
执行就可以看到异步方法使用的线程池了,不指定不写也可以,spring会给一个默认的简单异步线程池;

注意:

实现AsyncConfigurer接口只能实现一个类,否则会报错如下(很明显了):
Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Only one AsyncConfigurer may exist
我们甚至可以不实现AsyncConfigurer,我们可以在Spring环境中配置多个Executor类型的Bean,在使用@Async注解时,将注解的value指定为你Executor类型的BeanName,这样也可以就是不方便管理而已…
最后需要在需要异步的方法或者类上加上注解@Async就可以愉快的使用异步了…
当然异步执行还有很多东西,比如执行完成后返回参数,计数等等,这些在这篇就不写出来了,有空再整理.

世界上所有的不公平都是由于当事人能力不足造成的.
原文地址:https://www.cnblogs.com/javayida/p/13347069.html