@Async,@EnableAsync,AsyncConfigurer 自定义线程池

1. @Async

在spring中,可以通过@EnableAsync + @Async两个注解非常快捷的实现异步。步骤如下:

启动类加上: @EnableAsync注解 并且在service上加上@Async注解

@SpringBootApplication(
        exclude = {CodecsAutoConfiguration.class},
        scanBasePackages = {
        		"com.arvato.config",
        		"com.arvato.service",
                "com.arvato.controller"
        })
@EnableAsync
@MapperScan(basePackages = "com.arvato.mapper.config")
public class WebFluxApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebFluxApplication.class, args);
    }
}


@RestController
@RequestMapping("/wxwork/sync")
public class WxworkSyncController {

	@Autowired
	private  WxworkSyncService wxworkSyncService;

	@GetMapping
	public Mono sync() {
		// 异步处理业务
		wxworkSyncService.sync();
		return Mono.just("直接返回处理成功");
	}
	
}

@Service
public class WxworkSyncService {
	@Async
	public void sync() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(System.currentTimeMillis() + "--" + Thread.currentThread().getName());
	}
}

然后疯狂发请求测试异步情况,并且打印线程名。我们发现默认情况下,每一次调用都是开启一个新的线程,截图如下:

@Async,@EnableAsync,AsyncConfigurer 自定义线程池_第1张图片

可以看出来,@Async用的是SimpleAsyncTaskExecutor线程池,但是如果没有对SimpleAsyncTaskExecutor做策略配置的话,是不复用线程的,这是对服务器资源的浪费。 

2.自定义线程池

自定义线程池很简单,只要实现AsyncConfigurer接口,并且重写getAsyncExecutor方法。

import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
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.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;

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

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (ex, method, params) ->
                log.error("Unexpected error occurred invoking async method: " + method +
                        ", args: " + Arrays.toString(params), ex);
    }

    /**
     * 自定义异步线程池
     * @return executor
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(1000);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.setWaitForTasksToCompleteOnShutdown(false);
        // 设置拒绝策略
        executor.setRejectedExecutionHandler((r, e) -> {
            throw new RejectedExecutionException("Task " + r.toString() +
                    " rejected from " +
                    e.toString());
        });
        executor.initialize();
        return executor;
    }
}

再次发请求测试:

@Async,@EnableAsync,AsyncConfigurer 自定义线程池_第2张图片

你可能感兴趣的:(java)