定义一个配置类,实现AsyncConfigurer接口,如下:
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.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//最大线程数
threadPoolTaskExecutor.setMaxPoolSize(36);
//核心线程数
threadPoolTaskExecutor.setCorePoolSize(6);
//队列最大容量
threadPoolTaskExecutor.setQueueCapacity(16);
//最大线程存活时间
threadPoolTaskExecutor.setKeepAliveSeconds(6);
//自定义线程工厂
threadPoolTaskExecutor.setThreadFactory(new ThreadFactory() {
AtomicInteger atomicInteger = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "get线程" + atomicInteger.incrementAndGet());
}
});
//初始化线程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
/**
* 出现异常时的处理方式
*
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
重写getAsyncExecutor()方法,定义出需要返回怎样的线程池,重写getAsyncUncaughtExceptionHandler()方法,定义怎么处理线程池中线程抛出的异常。然后通过@Configuration注解注入IOC容器,通过@EnableAsync注解开启异步线程池。
写一个接口类AsyncService,如下:
public interface AsyncService {
void get() throws InterruptedException;
}
写一个AsyncServiceImpl类,实现AsyncService接口,如下:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
@Service
public class AsyncServiceImpl implements AsyncService {
public String getCurrentDateTime() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.now().format(formatter);
}
@Override
@Async
public void get() throws InterruptedException {
System.out.println(getCurrentDateTime() + ":【" + Thread.currentThread().getName() + "】" + "处理请求");
TimeUnit.SECONDS.sleep(6);
}
}
写一个AsyncServiceController,提供相应接口做测试,如下:
package com.example.springboot.codedemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@RestController
@RequestMapping("/async")
public class AsyncServiceController {
public String getCurrentDateTime() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return LocalDateTime.now().format(formatter);
}
@Autowired
private AsyncService asyncService;
@GetMapping("/get")
public void get() throws InterruptedException {
System.out.println(getCurrentDateTime() + ":【" + Thread.currentThread().getName() + "】" + "发出请求");
asyncService.get();
}
}
为了方便,以上的日期转换方法没有抽取出来单独成工具。
访问http://localhost:8080/async/get,输出结果如下:
从输出结果可以看到,请求是并发执行的,并没有等待6s,同时发出请求的线程和处理请求的线程也是不一样的。