什么是@Async
被@Async标注的方法,称之为异步方法,会被独立的线程所执行,调用者无需等待它执行完毕,也可以执行其他操作。@Async标注在类上,表明类的所有方法都是异步方法
@Async的具体使用
1、在项目启动类上加上@EnableAsync注解,表明开启异步调用
import com.uini.common.swagger.annotation.EnableCustomSwagger2;
import com.uini.common.web.annotation.EnableCustomConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableAsync;
import java.net.InetAddress;
import java.net.UnknownHostException;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCustomConfig
@EnableCustomSwagger2
@EnableAsync//开启异步调用
public class TradeApplication {
private static final Logger log = LoggerFactory.getLogger(TradeApplication.class);
public static void main(String[] args) {
//输出swagger路径
ConfigurableApplicationContext application = SpringApplication.run(TradeApplication.class, args);
Environment env = application.getEnvironment();
try {
log.info("swagger: http://{}:{}/swagger-ui.html",
InetAddress.getLocalHost().getHostAddress(),
env.getProperty("server.port")
);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
2、自定义线程池
1> bootstrap.yml 配置文件:
#异步线程池
async:
executor:
thread:
core_pool_size : 10
max_pool_size : 50
queue_capacity : 1000
keep_alive_seconds : 300
await_termination_millis: 60
2> config 配置文件:
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 核心线程数
*/
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
/**
* 最大线程数
*/
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
/**
* 队列最大长度
*/
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
/**
* 线程池维护线程所允许的空闲时间
*/
@Value("${async.executor.thread.keep_alive_seconds}")
private int keepAliveSeconds;
/**
* 设置线程中任务的等待时间
*/
@Value("${async.executor.thread.await_termination_millis}")
private int awaitTerminationMillis;
/**
* 线程池对拒绝任务(无线程可用)的处理策略
*/
private CallerRunsPolicy callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();
/**
* 线程的前缀
*/
private String threadNamePrefix = "AsyncExecutorThread-";
@Bean(name = "asyncExecutor")
public ThreadPoolTaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setAwaitTerminationMillis(awaitTerminationMillis);
executor.setRejectedExecutionHandler(callerRunsPolicy);
executor.setThreadNamePrefix(threadNamePrefix);
executor.setRejectedExecutionHandler(callerRunsPolicy);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}
}
3、编写异步线程方法
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncExecutorService {
@Async("asyncExecutor")
public void testExecutor1(){
System.out.println("测试异步执行001");
}
@Async("asyncExecutor")
public void testExecutor2(){
System.out.println("测试异步执行002");
}
@Async("asyncExecutor")
public void testExecutor3(){
System.out.println("测试异步执行003");
}
}
4、编写控制类,调用异步方法
import com.uini.trade.pay.async.AsyncExecutorService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Api(tags = "Async异步")
@RestController
@RequestMapping("/async")
public class AsyncExecutorController {
@Resource
private AsyncExecutorService asyncExecutorService;
@ApiOperation("测试执行")
@GetMapping("/testExecutor")
public void testExecutor() {
System.err.println("==========开始测试001===========");
asyncExecutorService.testExecutor1();
System.err.println("===========结束测试001==========");
System.err.println("==========开始测试002===========");
asyncExecutorService.testExecutor2();
System.err.println("===========结束测试002==========");
System.err.println("==========开始测试003===========");
asyncExecutorService.testExecutor3();
System.err.println("===========结束测试003==========");
}
}
5、运行程序,对 testExecutor() 方法进行多次访问,得到的结果:
备注: testExecutor() 方法内调用的三个异步方法不是按顺序输出的,证明异步调动生效。