package com.railway.framework.config;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.railway.common.utils.Threads;

/**
 * 线程池配置
 *
 * @author railway
 **/
@Configuration
public class ThreadPoolConfig {

  /**
   * 核心线程池大小
   */
  @Value("${thread.core-size:50}")
  private final int corePoolSize = 50;

  /**
   * 最大可创建的线程数
   */
  @Value("${thread.max-size:200}")
  private final int maxPoolSize = 200;

  /**
   * 队列最大长度
   */
  @Value("${thread.queue-size:1000}")
  private final int queueCapacity = 1000;

  /**
   * 线程池维护线程所允许的空闲时间
   */
  @Value("${thread.alive-time:600}")
  private final int keepAliveSeconds = 600;

  @Bean(name = "threadPoolTaskExecutor")
  public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setMaxPoolSize(maxPoolSize);
    executor.setCorePoolSize(corePoolSize);
    executor.setQueueCapacity(queueCapacity);
    executor.setKeepAliveSeconds(keepAliveSeconds);
    // 线程池对拒绝任务(无线程可用)的处理策略
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return executor;
  }

  /**
   * 执行周期性或定时任务
   */
  @Bean(name = "scheduledExecutorService")
  protected ScheduledExecutorService scheduledExecutorService() {
    return new ScheduledThreadPoolExecutor(corePoolSize,
        new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
      @Override
      protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        Threads.printException(r, t);
      }
    };
  }

  @Bean
  public ThreadPoolExecutor threadPoolExecutor() {
    return new ThreadPoolExecutor(
        corePoolSize, maxPoolSize, keepAliveSeconds, TimeUnit.SECONDS,
        //默认是Integer的最大值，内存肯定会不够。所以需要指定一个数量
        new LinkedBlockingQueue<>(queueCapacity),
        Executors.defaultThreadFactory(),
        //新进来的任务，直接丢弃
        new ThreadPoolExecutor.AbortPolicy());
  }
}
