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<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;
-
}
-
}
再次发请求测试: