/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved.
 * <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.concurrent;

import com.crunii.micro.common.utils.StopUtil;

import java.util.concurrent.*;

/**
 * @author 田平 create 2021/12/21 14:06
 */
public class PriorityExecutor extends ThreadPoolExecutor {

	private static final int INIT_SIZE = 128;

	public PriorityExecutor(int corePoolSize, int maximumPoolSize) {
		super(corePoolSize, maximumPoolSize, 0, TimeUnit.MINUTES,
				getPriorityQueue(INIT_SIZE));
	}

	public PriorityExecutor(int corePoolSize, int maximumPoolSize,
							long keepAliveTime, TimeUnit unit) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
				getPriorityQueue(INIT_SIZE));
	}

	public PriorityExecutor(int queueSize, int corePoolSize, int maximumPoolSize,
							long keepAliveTime, TimeUnit unit) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
				getPriorityQueue(queueSize));
	}

	public PriorityExecutor(int queueSize, int corePoolSize, int maximumPoolSize,
							long keepAliveTime, TimeUnit unit,
							ThreadFactory threadFactory) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
				getPriorityQueue(queueSize), threadFactory);
	}

	public PriorityExecutor(int queueSize, int corePoolSize, int maximumPoolSize,
							long keepAliveTime, TimeUnit unit,
							RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
				getPriorityQueue(queueSize), handler);
	}

	public PriorityExecutor(int queueSize, int corePoolSize, int maximumPoolSize,
							long keepAliveTime, TimeUnit unit,
							ThreadFactory threadFactory,
							RejectedExecutionHandler handler) {
		super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
				getPriorityQueue(queueSize), threadFactory, handler);
	}

	private static PriorityBlockingQueue getPriorityQueue(int size) {
		return new PriorityBlockingQueue(size);
	}

	public void execute(PriorityRunnable run) {
		super.execute(run);
	}

	public <T> Future<T> submit(PriorityRunnable run) {
		PriorityTask task = new PriorityTask(run, null);
		super.execute(task);
		return task;
	}

	public <T> Future<T> submit(PriorityRunnable run, T result) {
		PriorityTask task = new PriorityTask(run, result);
		super.execute(task);
		return task;
	}

	public <T> Future<T> submit(PriorityCallable<T> call) {
		PriorityTask task = new PriorityTask(call);
		super.execute(task);
		return task;
	}

	public <T> Future<T> submit(PriorityTask<T> task) {
		super.execute(task);
		return task;
	}

	public static void main(String[] args) throws Exception {
		//设置一个线程的邮箱线程池，方便查看效果
		PriorityExecutor executor = new PriorityExecutor(1, 1);
		CountDownLatch cd = new CountDownLatch(3);
		executor.execute(new PriorityRunnable(() -> {
			try {
				TimeUnit.MILLISECONDS.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(1);
			cd.countDown();
		}, 1));
		executor.execute(new PriorityRunnable(() -> {
			try {
				TimeUnit.MILLISECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(3);
			cd.countDown();
		}, 3));
		executor.execute(new PriorityRunnable(() -> {
			try {
				TimeUnit.MILLISECONDS.sleep(15);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(2);
			cd.countDown();
		}, 2));
		cd.await();
		StopUtil.stopES(executor);
	}

}
