首先在启动类上加上注解??
@EnableAsync 来开启异步
然后在实现类上给自己需要异步的方法加入异步注解?
@Async
代码部分: Controller
@RestController
@RequestMapping("demo/")
public class DemoController {
@Resource
private DemoService demoService;
@ApiOperation("demo")
@PostMapping("demo")
public LaunchVo demo() throws InterruptedException {
demoService.a();
demoService.b();
demoService.c();
return null;
}
}
Service
public interface DemoService {
/**
* 普通1
* @throws InterruptedException
*/
void a() throws InterruptedException;
/**
* 异步
* @throws InterruptedException
*/
void b() throws InterruptedException;
/**
* 普通2
* @throws InterruptedException
*/
void c() throws InterruptedException;
}
ServiceImpl
@Service
public class DemoServiceImpl implements DemoService {
@Override
public void a() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("正常1:"+i);
}
}
@Async
@Override
public void b() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("异步:"+i);
}
}
@Override
public void c() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("正常2:"+i);
}
}
}
运行结果
先执行的正常a方法,正常执行,在执行b和c的时候,正常是先要执行完b方法再执行c方法,因为b方法异步了,所以b,c两个方法结果成了交替,b方法异步执行
注意:直接使用?@Async 注解的线程池,默认的线程池无法实现线程重用,每次调用都会新建一条线程,会造成服务器占用内存过高,根据情况可以自己配置个线程池
代码
线程池配置
@Configuration
public class AsyncConfiguration {
private int corePoolSize = 10;
private int maxPoolSize = 100;
private int queueCapacity = 100;
private int KeepAliveSeconds = 200;
private String namePrefix = "async-";
@Bean(name = "asyncPoolTaskExecutor")
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数
executor.setCorePoolSize(corePoolSize);
//线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(maxPoolSize);
//缓存队列
executor.setQueueCapacity(queueCapacity);
//设置线程的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(KeepAliveSeconds);
//异步方法内部线程名称
executor.setThreadNamePrefix(namePrefix);
/**
* 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
* 通常有以下四种策略:
* ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
* ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
* ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
* ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
*/
//ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
ServiceImpl
注解 @Async("asyncPoolTaskExecutor") 指定线程池bean?asyncPoolTaskExecutor
@Service
public class DemoServiceImpl implements DemoService {
@Override
public void a() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("正常1:"+i);
}
}
@Async("asyncPoolTaskExecutor")
@Override
public void b() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("异步:"+i);
}
}
@Override
public void c() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(100);
System.out.println("正常2:"+i);
}
}
}
运行结果
使用自身配置的线程池,内存的问题就能得到控制