package com.artfess.base.thread;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Date 2021/11/12 4:40 下午
 * @Description 线程池
 */
@Setter
@Getter
@Configuration
@EnableAsync(proxyTargetClass = true)
public class DefaultAsycTaskConfig {
    /**
     *  线程池维护线程的最小数量.
     */
    @Value("${asyc-task.corePoolSize:10}")
    private int corePoolSize;
    /**
     *  线程池维护线程的最大数量
     */
    @Value("${asyc-task.maxPoolSize:20}")
    private int maxPoolSize;

    @Value("${asys-task.keepAliveTime:10}")
    private long keepAliveTime;

    /**
     *  队列最大长度
     */
    @Value("${asyc-task.queueCapacity:1000}")
    private int queueCapacity;
    /**
     *  线程池前缀
     */
    @Value("${asyc-task.threadNamePrefix:dmpExecutor-}")
    private String threadNamePrefix;

    private static final AtomicLong COUNTER = new AtomicLong();

    @Bean(name = "bmpExecutorService")
    public ExecutorService bmpExecutorService() {
        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat(threadNamePrefix + "%d").build();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maxPoolSize,
                keepAliveTime,
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(queueCapacity),
                threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    @Bean(name = "bmpSchedualedExecutorService")
    public ScheduledExecutorService bmpSchedualedExecutorService() {
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(
                corePoolSize,
                r -> new Thread(r,"common-scheduled-thread" + COUNTER.getAndIncrement()),
                new ThreadPoolExecutor.CallerRunsPolicy());
        return scheduledExecutorService;
    }

}