- @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<String> 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用的是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;
}
}