package cn.com.poc.common.pool;

import cn.com.yict.framemax.core.i18n.I18nMessageException;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 公共业务线程池
 *
 * 核心线程数：CPU核数
 * 最大线程数：CPU核数*20
 * 队列大小：CPU核数*2
 * 拒绝策略：CallerRunsPolicy
 * 线程池名称：Common_Thread_Executor
 * 是否为守护线程: false
 */
public class CommonThreadPoolExecutor {

    final private static String THREAD_POOL_NAME = "Common_Thread_Executor";

    final private static int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();

    final private static int MAXIMUM_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 20;

    final private static int KEEP_ALIVE_TIME = 60;

    final private static LinkedBlockingQueue<Runnable> WORK_QUEUE = new LinkedBlockingQueue<>(CORE_POOL_SIZE * 2);

    final private static Thread.UncaughtExceptionHandler EXCEPTION_HANDLER = new CommonThreadPoolExceptionHandler();

    final private static RejectedExecutionHandler REJECTED_EXECUTION_HANDLER =
            new ThreadPoolExecutor.CallerRunsPolicy();

    final private static ThreadFactory THREAD_FACTORY =
            new ThreadFactoryBuilder()
                    .setUncaughtExceptionHandler(EXCEPTION_HANDLER)
                    .setNameFormat(THREAD_POOL_NAME + "-%d")
                    .setDaemon(false)
                    .build();

    final private static ThreadPoolExecutor THREAD_POOL_EXECUTOR;

    static {
        THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAXIMUM_POOL_SIZE,
                KEEP_ALIVE_TIME,
                java.util.concurrent.TimeUnit.SECONDS,
                WORK_QUEUE,
                THREAD_FACTORY,
                REJECTED_EXECUTION_HANDLER
        );
    }

    public static void addTask(Runnable task) {
        try {
            THREAD_POOL_EXECUTOR.submit(task);
        } catch (Exception e) {
            throw new I18nMessageException("exception/there.are.too.many.tasks.currently.please.try.again.later");
        }
    }

    public static ThreadPoolExecutor getThreadPoolExecutor() {
        return THREAD_POOL_EXECUTOR;
    }

}
