package com.cyksj.common.task;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author chan
 * @className GlobalThreadPoolTaskExecutor
 * @description 全局任务异步处理
 * @date 2020-05-21 16:35
 */
@Component
public final class GlobalThreadPoolTaskExecutor {

	private static final Logger LOGGER = LoggerFactory.getLogger(GlobalThreadPoolTaskExecutor.class);
	
	private GlobalThreadPoolTaskExecutor() {
	}

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

	private static final ThreadPoolTaskExecutor POOLTASKEXECUTOR = new ThreadPoolTaskExecutor();

	static {
		// 队列深度.
		POOLTASKEXECUTOR.setQueueCapacity(Integer.MAX_VALUE);
		// 核心线程数.
		POOLTASKEXECUTOR.setCorePoolSize(CORE_SIZE * 4);
		// 最大线程数.
		POOLTASKEXECUTOR.setMaxPoolSize(CORE_SIZE * 4);
		// 线程名前缀.
		POOLTASKEXECUTOR.setThreadNamePrefix("DISPATCH_TASK_");
		// discard
		POOLTASKEXECUTOR.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

		POOLTASKEXECUTOR.initialize();
		POOLTASKEXECUTOR.getThreadPoolExecutor().prestartAllCoreThreads();
		
		LOGGER.info("线程池启动成功,CPU数: " + CORE_SIZE + ", 核心线程数: " + CORE_SIZE * 4);
	}

	private static final GlobalThreadPoolTaskExecutor INSTANCE = new GlobalThreadPoolTaskExecutor();

	/**
	 * 获取单例线程池对象
	 * 
	 * @author chan
	 * @return 单例对象
	 **/
	public static GlobalThreadPoolTaskExecutor getInstance() {
		return INSTANCE;
	}

	/**
	 * 提交异步任务
	 * 
	 * @author chan
	 * @param taskBean 任务
	 * @return void
	 **/
	public void execute(BaseTaskBean taskBean) {
		POOLTASKEXECUTOR.execute(taskBean);
	}

	/**
	 * 提交延迟异步任务
	 * 
	 * @author chan
	 * @param taskBean 任务
	 * @return void
	 **/
	public void execute(BaseTaskBeanDelayed taskBean) {
		POOLTASKEXECUTOR.execute(taskBean);
	}

	/**
	 * 提交异步任务
	 * 
	 * @author chan
	 * @param runTask 任务
	 * @return void
	 **/
	public void execute(Runnable runTask) {
		POOLTASKEXECUTOR.execute(runTask);
	}

	/**
	 * 提交异步任务
	 * 
	 * @author chan
	 * @param runTask 任务
	 * @return 返回异步任务执行结果
	 **/
	public <T> Future<T> submit(Callable<T> runTask) {
		return POOLTASKEXECUTOR.submit(runTask);
	}

	/**
	 * 提交异步任务
	 * 
	 * @author chan
	 * @param runTask 任务
	 * @return 返回异步任务执行结果
	 **/
	public ListenableFuture<?> submitListenable(Callable<?> runTask) {
		ListenableFuture<?> futrue = POOLTASKEXECUTOR.submitListenable(runTask);
		return futrue;
	}
}
