使用场景:发送邮件、日志记录、发短信等属于单一任务、耗时的非事务型操作,在简单的使用场景下使用异步方法调用可以快速实现。如场景较为复杂建议使用消息中间件服务(MQ),注意异步方法在执行期间如果服务被终止则可能造成任务被取消,需要自行实现数据恢复。
以下演示2个异步调用方法,分别使用不同的 Executor:
(1)一个是无需等待返回的异步方法;
(2)一个是利用Future的异步调用方法,可接收返回值。
一、定义异步Executor(线程池)
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@EnableAsync // 启动异步调用
@Configuration
public class AsyncConfigSupport extends AsyncConfigurerSupport {
@Bean(name = "executorOne")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("CSISTP-");
executor.initialize();
return executor;
}
@Bean
public Executor executorTwo() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(100);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("CSISTP-");
executor.initialize();
return executor;
}
}
二、在需要进行异步调用的方法增加异步调用注解,2个方法分别使用不同的 Executor
@Service
public class ExampleService{
@Async("executorOne") // 可以不指定,默认使用 getAsyncExecutor (即本示例的 executorOne)
public void notifyMessageWithoutReturn(){
try {
log.info("notifyMessageWithoutReturn...");
log.info("notifyMessage>wait...");
Thread.sleep(1000*3);
log.info("notifyMessage>OK!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Async("executorTwo")
public Future<String> notifyMessageWithReturn(){
Future<String> future;
try {
log.info("notifyMessageWithReturn...");
Thread.sleep(1000 * 3);
future = new AsyncResult<String>("success!" );
} catch (InterruptedException e) {
future = new AsyncResult<String>("error");
}
return future;
}
}
三、方法调用测试
@Autowired
ExampleService exampleService
@Test
public void testAsync() throws Exception {
// 同步方法调用
this.exampleService.notifyMessageWithoutReturn();
Future<String> future = this.exampleService.notifyMessageWithReturn();
while(true){
// 等待返回
if (future.isDone()){
System.out.println("done, result="+future.get());
break;
}
System.out.println("not finish yet");
Thread.sleep(100);
}
}
网友评论