1.在项目中有些时候,需要异步执行一些代码,除了使用线程、线程池等方式,还可以使用@Async 注解实现
2.直接上代码
1)配置类:
package com.example.demo.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @Author: cm
* @CreateTime: 2022/5/24 14:44
* @Description: 异步执行的代码封装成一个方法,然后用@Async注解该方法,
* 然后在主方法中直接调用
* @Async注解的方法与调用方法不能在同一个类中,否则不生效
*/
@Configuration
public class AsyncConfig {
Logger logger = LoggerFactory.getLogger(TestApplication.class);
@Async
public void asyncMethod() {
logger.info("异步代码---开始---"
+ new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss").format(new Date()));
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("异步代码---结束---"
+ new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss").format(new Date()));
}
// 配置线程池,如果不配置也能用,但是会提示:No task executor bean found for async processing: no bean of type TaskExecut
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(5);
// 设置最大线程数
executor.setMaxPoolSize(10);
// 设置队列容量
executor.setQueueCapacity(20);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
// 设置默认线程名称
executor.setThreadNamePrefix("test-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}
2)启动类:
package com.example.demo.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* @Author: cm
* @CreateTime: 2022/5/30 9:34
* @Description: 启动类
*/
@SpringBootApplication
@EnableAsync
public class TestApplication {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(TestApplication.class);
SpringApplication.run(TestApplication.class, args);
logger.info("测试--------->>>>>>微服务启动成功");
}
}
3)controller:
package com.example.demo.async;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @Author: cm
* @CreateTime: 2022/5/30 9:54
* @Description: controller
*/
@RestController
public class TestController {
Logger logger = LoggerFactory.getLogger(TestApplication.class);
@Autowired
AsyncConfig asyncConfig;
@GetMapping("/testAsync")
public void Test() {
logger.info("主代码---开始---"
+ new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss").format(new Date()));
asyncConfig.asyncMethod();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("主代码---结束---"
+ new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss").format(new Date()));
}
}
启动主类后,可以使用 postman 测试,测试结果如下:
注意:
1)启动类添加 @EnableAsync 开启异步服务
2)定义和调用带有 @Async 注解方法不能在同一个类中