springboot与多线程(@Async 注解)

一、定义和理解:

工作中经常涉及异步任务,通常是使用多线程技术,比如线程池ThreadPoolExecutor,它的执行规则如下:
在这里插入图片描述
在Springboot中对其进行了简化处理,只需要配置一个类型为java.util.concurrent.TaskExecutor或其子类的bean,并在配置类或直接在程序入口类上声明注解 @EnableAsync

调用也简单,在由Spring管理的对象的方法上标注注解@Async,显式调用即可生效。

一般使用Spring提供的ThreadPoolTaskExecutor类。

二、声明:

@Configuration
@EnableAsync
public class BeanConfig {

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

三、调用:

@Component
public class Hello {
    @Async
    public void sayHello(String name) {
        LoggerFactory.getLogger(Hello.class).info(name + ":Hello World!");
    }
}

测试:
在这里插入图片描述
从打印日志中可以看出线程池已经正常工作了。

四、进阶

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

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

五、调用返回值:

    @Autowired
    private Hello hello;

    // 阻塞调用
    hello.sayHello("yan").get();
    // 限时调用
    hello.sayHello("yan").get(1, TimeUnit.SECONDS)

六、补充

实际上,@Async 还有一个参数,通过Bean名称来指定调用的线程池-比如上例中设置的线程池参数不满足业务需求,可以另外定义合适的线程池,调用时指明使用这个线程池-缺省时springboot会优先使用名称为’taskExecutor’的线程池,如果没有找到,才会使用其他类型为TaskExecutor或其子类的线程池。

参考链接:

  1. Springboot学习笔记(一)-线程池的简化及使用
  2. Spring Boot中使用@Async实现异步调用
  3. Spring Boot使用@Async实现异步调用:自定义线程池
  4. Spring @Async之二:SpringBoot 自定义线程池,修改springboot的默认线程池
  5. springboot-@Async默认线程池导致OOM问题
  6. ThreadPoolExecutor使用详解
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值