1、在SpringApplication上添加@EnableAsync
package com.cn.dl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SpringBootRocketmqApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootRocketmqApplication.class, args);
}
}
2、在需要异步的方法上添加@Async
package com.cn.dl.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* Created by yanshao on 2019/3/11.
*/
// TODO: 2019/3/11 加了@Component或者@Service就可以启动,不能再同一个类中调用
// TODO: 2019/3/11 加@Async()注解的类不能用static修饰
// TODO: 2019/3/11 加@Async()注解的类可以用protected修饰
// TODO: 2019/3/11 加@Async()注解的类可以无访问修饰符
// TODO: 2019/3/11 加@Async()注解的类,因为调用者和被调用者不能在同一个类中,所以不能用private修饰
@Component
@Slf4j
public class AsyncService {
@Async()
public void async(){
try {
TimeUnit.SECONDS.sleep(5);
log.info("async>>>>>>>>>>>>>>>>异步输出");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async()
public void async1(){
try {
TimeUnit.SECONDS.sleep(5);
log.info("async>>>>>>>>>>>>>>>>异步输出");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
需要注意的地方:
// TODO: 2019/3/11 加了@Component或者@Service就可以启动,不能再同一个类中调用
// TODO: 2019/3/11 加@Async()注解的类不能用static修饰
// TODO: 2019/3/11 加@Async()注解的类可以用protected修饰
// TODO: 2019/3/11 加@Async()注解的类可以无访问修饰符
// TODO: 2019/3/11 加@Async()注解的类,因为调用者和被调用者不能在同一个类中,所以不能用private修饰
这样就可以启动SpringBoot来使用了!但是每次都是新启一个线程,浪费资源,因此需要配置线程池!
package com.cn.dl.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by yanshao on 2019/3/11.
*/
@RestController
@RequestMapping({"/api/enscy"})
public class AsyncController {
@Autowired
AsyncService asyncService;
@PostMapping("/test")
public void enscy(){
System.out.println("enscy >>>>>> 异步输出");
asyncService.async();
}
@PostMapping("/test1")
public void async(){
System.out.println("enscy >>>>>> 异步输出");
asyncService.async1();
}
}
postman中访问127.0.0.1:8080/api/enscy/test1
enscy >>>>>> 异步输出
enscy >>>>>> 异步输出
2019-03-11 19:27:52.425 INFO 15048 --- [ task-1] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
enscy >>>>>> 异步输出
enscy >>>>>> 异步输出
2019-03-11 19:27:57.229 INFO 15048 --- [ task-2] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
2019-03-11 19:27:57.479 INFO 15048 --- [ task-3] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
2019-03-11 19:27:57.842 INFO 15048 --- [ task-4] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
3、配置线程池
package com.cn.dl.config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* Created by yanshao on 2019/3/11.
*/
@SpringBootConfiguration
public class AysncConfig {
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor getAsyncThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(20);
taskExecutor.setMaxPoolSize(200);
taskExecutor.setQueueCapacity(25);
taskExecutor.setKeepAliveSeconds(200);
taskExecutor.setThreadNamePrefix("yanshao-");
taskExecutor.initialize();
return taskExecutor;
}
}
enscy >>>>>> 异步输出
enscy >>>>>> 异步输出
enscy >>>>>> 异步输出
2019-03-11 19:31:43.314 INFO 7976 --- [ yanshao-1] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
2019-03-11 19:31:43.526 INFO 7976 --- [ yanshao-2] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
2019-03-11 19:31:43.838 INFO 7976 --- [ yanshao-3] com.cn.dl.controller.AsyncService : async>>>>>>>>>>>>>>>>异步输出
发现线程名已yanshao-开头来命名,说明配置生效了!
4、四个配置参数说明
corePoolSize:线程池维护线程的最少数量
keepAliveSeconds:允许的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
maxPoolSize:线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
queueCapacity:缓存队列