• SpringBoot的线程调度


    Spring Boot默认提供了一个ThreadPoolTaskExecutor作为线程调度器,只需要在配置类中使用注解EnableAsync即可开启异步线程调度。在实际要执行的Bean中使用@Async注解来声明这个方法是异步方法,需要通过线程调度器来执行。

    示例代码如下:

    Application类,开启异步线程调度

    @SpringBootApplication
    @EnableAsync
    public class TestApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(TestApplication.class, args);
    	}
    }
    

    异步任务类,声明execute()方法通过线程调度器执行

    @Service
    public class TestAsync {
      
      private static AtomicInteger count = new AtomicInteger(0);
    
      @Async
      public String execute() {
        System.out.println("begin execute TestAsync: " + count.incrementAndGet());
        try {
          Thread.sleep(10000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("finished execute TestAsync");
        return "result";
      }
    }
    

    要注意的问题:

    (1)这里的@Async注解必须要声明在Bean对外提供的方法上,如果这个方法不是由其它类直接调用,而是这个类的其它方法间接调用,则不生效。
    (2)@Async注解声明的方法,返回类型要么声明为void,要么声明为Future。因为方法是异步调用,因此无法立即返回结果,如果声明为其它返回类型,则获取到的是null。声明为Future,则可以获取到任务的执行结果。

    Controller类

    @RestController
    public class TestAsyncController {
      
      @Autowired
      private TestAsync testAsync;
      
      @RequestMapping(value = "/async", method = RequestMethod.GET)
      public String async() {
        System.out.println("before execute TestAsync");
        String result =  testAsync.outexecute();
        System.out.println("after execute TestAsync");
        return result;
      }
    }

    这里获取到的result值null,因此获取这个返回值没有什么意义。

    Spring Boot线程调度有以下几个参数可以配置(2.1版本之后才有):
    spring.task.execution.pool.core-size # 核心线程数,默认为8
    spring.task.execution.pool.queue-capacity # 队列容量,默认为无限大
    spring.task.execution.pool.max-size # 最大线程数,默认为无限大
    这三个参数的关系如下:
    如果当前要执行的任务数超过core-size,则任务会放到队列里面等待执行,等核心线程中有任务执行完成之后,再取出队列中的任务进行调度执行。
    如果等待队列已经满了,再收到新任务时,则核心线程会自动扩容,最大扩展到max-size。

    spring.task.execution.pool.allow-core-thread-timeout # 是否允许回收空闲的线程,默认为true
    spring.task.execution.pool.keep-alive # 空闲的线程可以保留多少秒,默认为60。如果超过这个时间没有任务调度,则线程会被回收
    spring.task.execution.thread-name-prefix # 线程名前缀,默认为thread-

    自定义线程调度器
    如果不想使用Spring Boot自带的线程调度器,可以通过实现AsyncConfigurer接口来定义自己的线程调度器。
    示例代码如下: 

    @Configuration
    @EnableAsync
    public class AppConfig implements AsyncConfigurer {
    
      @Override
      public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(7);
        executor.setMaxPoolSize(42);
        executor.setQueueCapacity(11);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.initialize();
        return executor;
      }
    
      @Override
      public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return MyAsyncUncaughtExceptionHandler();
      }
    }
    

      

  • 相关阅读:
    iOS:网络检测
    WinJS:设置listView垂直滚动
    iOS:在AppDelegate中定义managed object context
    简笔画项目总结: ios绘图机制 & 实现记录笔迹功能
    CSS基础
    DOM小结
    iOS:view.frame
    WP:初探
    iOS:UIWebView scrollView 的分页滑动问题
    Mono for Android: 利用mono for android开发的第一个程序
  • 原文地址:https://www.cnblogs.com/lasdaybg/p/10161249.html
Copyright © 2020-2023  润新知