package com.skr.mdm.util;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * MDM线程池工具类
 * @date 2023-08-08 11:09:33
 */
@Slf4j
public class MdmThreadPoolUtil {
	/**
	 * 使用volatile关键字保其可见性
	 */
	private volatile static ThreadPoolExecutor threadPool = null;

	/**
	 * 无返回值直接执行
	 *
	 * @param runnable
	 */
	public static void execute(Runnable runnable) {
		getThreadPool().execute(runnable);
	}

	/**
	 * 返回值直接执行
	 *
	 * @param callable
	 */
	public static <T> Future<T> submit(Callable<T> callable) {
		return getThreadPool().submit(callable);
	}

	public static ThreadPoolExecutor getThreadPool() {
		try {
			if (threadPool == null) {
				synchronized (MdmThreadPoolUtil.class) {
					//二次检查
					if (threadPool == null) {
						ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("MDM-pool-%d").build();
						// 获取处理器数量
						int cpuNum = Runtime.getRuntime().availableProcessors();
						log.info("CPU处理器核心数：{}", cpuNum);
						// 根据cpu数量,计算出合理的线程并发数
						int threadNum = cpuNum * 2 + 1;
						threadPool = new ThreadPoolExecutor(
								// 核心线程数
								threadNum - 1,
								// 最大线程数
								threadNum,
								// 闲置线程存活时间
								60L,
								// 时间单位
								TimeUnit.SECONDS,
								// 线程队列
								new LinkedBlockingDeque<Runnable>(1000),
								// 线程工厂
								threadFactory,
								// 队列已满,而且当前线程数已经超过最大线程数时的异常处理策略
								new ThreadPoolExecutor.CallerRunsPolicy() {
									@Override
									public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
										log.warn("MDM线程池任务已满，执行拒绝策略");
										super.rejectedExecution(r, e);
										log.info("拒绝策略触发调用者线程执行成功");
									}
								}
						);
						log.info("MDM线程池初始化完成");
					}
				}
			}
		} catch (Exception e) {
			log.error("MDM线程池初始化失败", e);
		}
		return threadPool;
	}

}