线程池正确打开方式- 拌饭使用效果更佳

Posted nightofstreet

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池正确打开方式- 拌饭使用效果更佳相关的知识,希望对你有一定的参考价值。

为什么要用线程池?什么是线程池?怎么使用?素质三连!!!

  1. 为什么要用线程池?
    1. 节约系统资源。避免反复创建销毁线程
    2. 提供异步操作。提高响应速度
    3. 方便管理线程
  2. 什么是线程池?
    1. 多线程使用的一种管理方式。池化技术能有效的利用和管理一些资源
  3. 怎么使用?
    1. 当然是配合springboot使用。皮一下??
    2. 整个过程梳理如下
      1. 让IOC容器加载和管理线程池 - 即配置完成之后,项目启动便加载配置
      2. 调用时使用注解 - 方便开发

线程池核心概念介绍

  • corePoolSize 正常持有的线程数。在使用线程时,如果池中的线程数小于该数,会创建新线程
  • maximumPoolSize  允许拥有的最大线程数。 池中核心线程core如果超出了,会放到阻塞队列中。队列如果也满了,会申请创建线程但数量不能超过该数值。如果超过了会执行拒绝策略
  • BlockingQueue<Runnable> workQueue 阻塞队列,用于存放等待资源的线程。
  • long keepAliveTime,TimeUnit unit  大于核心线程数的线程空闲之后的存活时间。活着浪费空气

实际配置如下      

  1. 启动类上添加@EnableConfigurationProperties 注解。用于解析自定义配置属性。同时需要引入pom配置
    1. @EnableConfigurationProperties
      public class MerchantApplication {
          public static void main(String[] args) {
              SpringApplication.run(MerchantApplication.class, args);
          }
      }
      
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
          <optional>true</optional>
      </dependency>
  2. 配置启动加载时需要的类。1.yml配置属性。2.配置类启动加载

    1. // yml配置
      task:
        pool:
          corePoolSize: 5
          queueCapacity: 20
          maxPoolSize: 10
          keepAliveSeconds: 3
      
      // 属性映射类
      @Data
      @ConfigurationProperties(prefix = "task.pool")
      @Component
      public class TaskThreadPoolProperty {
      
          private int corePoolSize;
      
          private int maxPoolSize;
      
          private int keepAliveSeconds;
      
          private int queueCapacity;
      
      }

      // 启动加载
      @Configuration
      @EnableAsync
      public class ThreadPoolConfig {

      @Resource
      private TaskThreadPoolProperty config;

      /**
      * 默认使用 名为 taskExecutor 的线程池
      *
      * @return 初始化线程池
      */
      @Bean("taskExecutor")
      public Executor configTaskAsyncPool() {
      ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
      //核心线程池大小
      executor.setCorePoolSize(config.getCorePoolSize());
      //最大线程数
      executor.setMaxPoolSize(config.getMaxPoolSize());
      //队列容量
      executor.setQueueCapacity(config.getQueueCapacity());
      //活跃时间
      executor.setKeepAliveSeconds(config.getKeepAliveSeconds());
      //线程名字前缀
      executor.setThreadNamePrefix("Qc-");
      // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行
      executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
      executor.setWaitForTasksToCompleteOnShutdown(true);
      return executor;
      }

      }  
  3. 调用 使用@Async注解调用
    1. // 实现异步操作的类
      @Component
      public class AsyncMessage {
      
          @Async
          public void sendMsgCL(String mobile, String content) {
              try {
                  Thread.sleep(3000L);
                  System.out.println("多线程异步执行" + "  " + Thread.currentThread().getName());
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
      // 测试异步的接口
        @Resource
          private AsyncMessage message;
      
          @PostMapping("/data1")
          public void data() {
              message.sendMsgCL(null, null);
              System.out.println("haha");
          }         
        
  4. 注意点(如果不注意可能会让你多吃两碗)
    1. 配置yml自定义属性之后需要重启IDEA才能生效。
    2. 启动加载的bean命名为@Bean("taskExecutor") 。spring在调用线程池时默认的池子名称为taskExecutor
    3. 使用@Async注解可以指明使用的线程池
      1. 不能修饰静态static方法
      2. 异步类需要被IOC容器管理。即要使用注解类似@Component @Service 。。。等等
      3. 异步方法不能与被调用的异步方法在同一个类中
      4. @EnableAsync 记得加上。可以在启动类上也可以在配置类上。

 

 

以上是关于线程池正确打开方式- 拌饭使用效果更佳的主要内容,如果未能解决你的问题,请参考以下文章

JAVA 递归线程池 ExecutorService / ForkJoinPool

Android 多线程下载,断点续传,线程池

线程池执行器异常

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

分享WeX5的正确打开方式——绑定机制

如何正确停止线程