由于 我的springboot2.x 使用带返回值的异步任务实现多线程并发任务[一] 讲述了多线程处理任务,但实现原理更复杂,代码量更多,可配置性差。 故而在 springboot官网英文文档翻译过来一种新的用法, 使用更简洁,可配置性更高。【实际项目推荐这种方法】
- 创建异步多线程配置任务类
package cn.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync// 开启异步任务[多线程下运行],在此处配置开启异步线程,则在主启动类不需要开启
public class AsyncThreadConfiguration
{
@Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(30);// 核心线程数
executor.setMaxPoolSize(30);// 并发线程的数量限制为2
executor.setQueueCapacity(500); // 线程队列
executor.setThreadNamePrefix("GithubLookup-");
executor.initialize();
return executor;
}
}
- 创建带返回值的两个异步任务 此处一般在service层, 当然也可以在其他任何层
@Service
public class IndexServices {
/**
* 相当于新开一个线程发送短信
* @return
* @throws InterruptedException
*/
@Async
public CompletableFuture<String> sendSms() throws InterruptedException {
Thread.sleep(3000L);
String results = "success";
return CompletableFuture.completedFuture(results);
}
/**
* 相当于新开一个线程 发送邮件
*/
@Async
public CompletableFuture<String> sendMailer() throws InterruptedException {
Thread.sleep(8000L);
String results = "failed";
return CompletableFuture.completedFuture(results);
}
}
- 在 controller中测试
@GetMapping("v2")
public String v2(
HttpServletRequest $request,
HttpServletResponse $response
) throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
CompletableFuture<String> sendSms= indexServices.sendSms();// 新开一个线程执行短信发送
CompletableFuture<String> sendMailer= indexServices.sendMailer();// 新开一个线程用于发送邮件
CompletableFuture.allOf(sendSms,sendMailer).join();// 阻塞等待结果的返回
String result1= sendMailer.get(); // 得到发送邮件的结果
String result2= sendSms.get(); // 得到发送短信的结果
log.warn("发送邮件的结果是:" + result1);
log.warn("发送短信的结果是:" + result2);
float exc = (float)(System.currentTimeMillis() - start)/1000;
System.out.println("执行总耗时:"+exc);
return "";
}
根据结果测试发现 两个任务执行全部执行完成在 8-9 s 之间; 如果没有使用线程异步任务,则耗时在11-12 s之间。
网友评论