您的位置:

SpringBoot自定义线程池

一、SpringBoot自定义线程池最多多少

线程池的大小是由应用程序负责创建的任务决定的。用不太科学的方法来设置线程池的大小,可能会导致应用程序出现各种问题和运行瓶颈。在Springboot中,线程池的大小可能会影响应用程序的吞吐量和可伸缩性。

在Thread类中,在构造函数中提供了一个参数,可以指定线程池最大线程数。该变量名是MAX_THREADS。在Springboot中,我们可以在配置文件中通过设置spring.task.execution.pool.max-threads属性来设置线程池的大小。

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(100);
    executor.setQueueCapacity(5);
    executor.setThreadNamePrefix("CustomThreadpoolDemo");
    executor.initialize();
    return executor;
  }
}

二、SpringBoot自定义线程池异常

当线程池出现异常或线程池中的任务执行出现异常时,我们可以使用异常处理程序捕获和处理异常。

Springboot内置了一个线程池异常处理程序,在发生未捕获异常时,将自动使用该处理程序。可以为ThreadPoolTaskExecutor指定一个AsyncUncaughtExceptionHandler,以便在发生异常时向处理程序发送信息。

@Configuration
@EnableAsync
public class AsyncConfigWithExceptionHandler implements AsyncConfigurer {

  @Override
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(100);
    executor.setQueueCapacity(5);
    executor.setThreadNamePrefix("CustomThreadpoolDemo");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }

  @Override
  public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    return new CustomAsyncExceptionHandler();
  }
 
  private static class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
      log.error("Exception message - " + ex.getMessage());
      log.error("Method name - " + method.getName());
      for (Object param : params) {
        log.error("Parameter value - " + param);
      }
    }
  }
}

三、SpringBoot自定义线程池无效

在Springboot中,初学者可能会遇到线程池无效的问题。如果在应用程序中配置了线程池,则只有使用@Async注释的方法才可以在其中运行。设置了线程池时,Springboot会尝试在其中查询该注释的方法,并调用其中方法的副本。

在使用Springboot自定义线程池的方法上添加@Async注解,以使该方法在配置的线程池中运行。如果没有注入线程池,则可能会调用原始方法。

@Service
public class UserServiceImpl implements UserService{

  @Autowired
  private UserRepository userRepository;

  @Autowired
  private NumberService numberService;

  @Override
  @Async("customAsyncExecutor")
  public CompletableFuture findById(Long id) {
    User user = userRepository.findById(id).orElse(null);
    int randomNumber = numberService.generateRandomNumber();
    user.setRandomNumber(randomNumber);
    return CompletableFuture.completedFuture(user);
  }
}

  

四、SpringBoot自定义线程池异步执行

在Springboot中,异步执行非常常见,并且可以通过简单地使用@Async注解来实现。使用@Async注解的方法在后台线程池中运行,并立即返回,而不必等待方法返回。

@Service
public class NotificationServiceImpl implements NotificationService {

  @Async("emailSendPool")
  @Override
  public CompletableFuture sendEmailNotification(String email, String message) {
    log.info("Send email to " + email);
    //send email logic
    return CompletableFuture.completedFuture("Email sent successfully to " + email);
  }

  @Async("smsSendPool")
  @Override
  public CompletableFuture
    sendSmsNotification(String phoneNumber, String message) {
    log.info("Send sms to " + phoneNumber);
    //send sms logic
    return CompletableFuture.completedFuture("SMS sent successfully to " + phoneNumber);
  }
}

   
  

五、基于SpringBoot自定义线程池

基于Springboot自定义线程池可以帮助应用程序实现异步事件处理。除了使用@Async注解外,还可以使用Springboot的基于事件的编程模型来自定义异步操作。

@Component
public class CartEventListener {

  @Async("cartStateChangePool")
  @EventListener
  public void cartChangeListener(ShoppingCartStateChangedEvent event) {
    //perform cart state change logic
    log.info("Shopping Cart state changed: " + event.getShoppingCart().getState());
  }
}

六、@Async自定义线程池

Springboot的@Async注解可以使用自定义线程池来调用应用程序的异步方法。使用@Async时,如果未提供自定义执行器,则会使用默认线程池。

@Configuration
@EnableAsync
public class AsyncConfig {

  @Bean("customAsyncExecutor")
  public Executor customAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(100);
    executor.setQueueCapacity(5);
    executor.setThreadNamePrefix("CustomThreadpoolDemo");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }
}

七、CompleteFuture自定义线程池

使用CompleteFuture可以帮助我们编写更清晰,更简单且更易于扩展的代码,因为我们可以利用CompleteFuture的方法链将片段组合在一起。

@Service
public class OrderServiceImpl implements OrderService {

  @Autowired
  private UserService userService;

  @Autowired
  private ProductService productService;

  @Async("customAsyncExecutor")
  @Override
  public CompletableFuture placeOrder(Long userId, Long productId) {
    CompletableFuture
    userFuture = userService.findById(userId);
    CompletableFuture
     productFuture = productService.findById(productId);

    return userFuture.thenCombine(productFuture, (user, product) -> {
        Order order = new Order();
        order.setUser(user);
        order.setProduct(product);
        order.setOrderDate(LocalDateTime.now());
        return order;
    });
  }
}

    
   
  

八、自定义线程池7个参数

在Springboot中,使用ThreadPoolTaskExecutor可以自定义线程池。可以通过以下七个参数设置线程池:

1. corePoolSize:线程池的大小(默认情况下5)

2. maxPoolSize:线程池的最大大小(默认情况下10)

3. queueCapacity:队列大小(默认情况下100)

4. keepAliveTime:线程池的线程保持活动的时间(默认情况下60s)

5. threadNamePrefix:每个线程的名称前缀(默认情况下“thread”)

6. rejectedExecutionHandler:拒绝策略(默认情况下使用ThreadPoolExecutor.CallerRunsPolicy)

7. allowCoreThreadTimeout:是否允许核心线程在空闲时间超过keepAliveTime时被回收(默认情况下为false)

@Configuration
@EnableAsync
public class AsyncConfig {

  @Bean("customAsyncExecutor")
  public ThreadPoolTaskExecutor customAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(100);
    executor.setQueueCapacity(5);
    executor.setThreadNamePrefix("CustomThreadpoolDemo");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }
}