• Springboot学习笔记(一)-线程池的简化及使用


    工作中经常涉及异步任务,通常是使用多线程技术,比如线程池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)
    

    补充

    1. 实际上,@Async还有一个参数,通过Bean名称来指定调用的线程池-比如上例中设置的线程池参数不满足业务需求,可以另外定义合适的线程池,调用时指明使用这个线程池-缺省时springboot会优先使用名称为'taskExecutor'的线程池,如果没有找到,才会使用其他类型为TaskExecutor或其子类的线程池。
    2. 个人觉得这篇文章还不错:https://www.cnblogs.com/zedosu/p/6665306.html
  • 相关阅读:
    多线程之同步代码块与同步函数
    图片上传客户端与服务端
    tcp上传学习二--文本文件上传
    javaScript编写9*9口诀
    tcp聊天
    udp聊天室--简易
    往sencha.cmd中恢复设计项时,不论是系统的还是应用的,恢复进去之后都应该一键发布到前端
    一个设计项上的按钮调另一个设计项的列表界面,同时加筛选条件
    点击【****】设计项上的某个按钮,直接调出另一个设计项的【编辑界面】
    前端向后端发送请求,后端返回的一个值的请求的ajax.get();方法
  • 原文地址:https://www.cnblogs.com/yw0219/p/8810956.html
Copyright © 2020-2023  润新知