目录
  1. 需要的注解
    1. @EnableAsync
    2. @Async
  2. 配置代码
  3. Service
  4. 进阶:带返回值的异步任务
  5. 调用
SpringBoot通过任务执行器(TaskExecutor)来进行多线程和并发编程

  我们在实际项目中有些复杂运算、耗时操作,就可以利用多线程来充分利用CPU,提高系统吞吐量。SpringBoot对多线程支持非常好,对我们的开发非常便捷。

  在Springboot中对其进行了简化处理,只需要配置一个类型为java.util.concurrent.TaskExecutor或其子类的bean,并在配置类或直接在程序入口类上声明注解@EnableAsync。调用也简单,在由Spring管理的对象的方法上标注注解@Async,显式调用即可生效。一般使用Spring提供的ThreadPoolTaskExecutor类。

需要的注解

springboot 配置多线程需要两个注解

  1. @EnableAsync

在配置类中通过加@EnableAsync开启对异步任务的支持

  1. @Async

在需要执行的方法上加@Async表明该方法是个异步方法,如果加在类级别上,则表明类所有的方法都是异步方法

配置代码

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 设置核心线程数
taskExecutor.setCorePoolSize(5);
// 设置最大线程数
taskExecutor.setMaxPoolSize(10);
// 设置队列容量
taskExecutor.setQueueCapacity(20);
// 设置线程活跃时间(秒)
taskExecutor.setKeepAliveSeconds(60);
// 设置默认线程名称
taskExecutor.setThreadNamePrefix("hello-");
// 设置拒绝策略
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
taskExecutor.initialize();
return taskExecutor;
}
}

Service

这里的方法自动被注入使用上文配置的ThreadPoolTaskExecutor

@Service
public class AsyncService {
@Async
public void executeAsync1() {
try {
Thread.sleep(20);
LoggerFactory.getLogger(AsyncService.class).info("异步任务::1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Async
public void executeAsync2() {
LoggerFactory.getLogger(AsyncService.class).info("异步任务::2");
}
}

进阶:带返回值的异步任务

有时候我们不止希望异步执行任务,还希望任务执行完成后会有一个返回值,在java中提供了Future泛型接口,用来接收任务执行结果,springboot也提供了此类支持,使用实现了ListenableFuture接口的类如AsyncResult来作为返回值的载体。比如上例中,我们希望返回一个类型为String类型的值,可以将返回值改造为:

@Service
public class AsyncService {
@Async
public void executeAsync1() {
try {
Thread.sleep(20);
LoggerFactory.getLogger(AsyncService.class).info("异步任务::1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}

@Async
public void executeAsync2() {
LoggerFactory.getLogger(AsyncService.class).info("异步任务::2");
}

@Async
public ListenableFuture<String> sayHello(String name) {
String res = name + ":Hello World!";
LoggerFactory.getLogger(AsyncService.class).info(res);
return new AsyncResult<>(res);
}

}

调用

@SpringBootApplication
public class TaskExecutorApplication implements CommandLineRunner {
@Autowired
private ApplicationContext context;

public static void main(String[] args) {
SpringApplication.run( TaskExecutorApplication.class, args );
}

@Override
public void run(String... strings){
AsyncService asyncService = context.getBean(AsyncService.class);
try {
for (int i = 0; i < 10; i++) {
asyncService.executeAsync1();
asyncService.executeAsync2();
}
Thread.sleep(1000);
// 阻塞调用
asyncService.sayHello("yan").get();
// 限时调用
asyncService.sayHello("yan").get(1, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}
}

}
文章作者: Gadfly
文章链接: https://blog.gadfly.pub/2019/12/13/cheng-xu-she-ji/springboot-tong-guo-ren-wu-zhi-xing-qi-taskexecutor-lai-jin-xing-duo-xian-cheng-he-bing-fa-bian-cheng/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 牛虻的世界
打赏
  • 微信
  • 支付寶

评论