package cn.freemud.utils;/**
 * @author wangxinqi1
 * @Date 2019/2/22 16:32
 */

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;

/**
 * @program: micro_progeram_service
 * @description: ThreadPoolUtil
 * @author: xinqi.wang
 * @create: 2019-02-22 16:32
 **/
public class ThreadPoolUtil {
    
    private static final ExecutorService DEF_THREADPOOL;
    
    static {
        DEF_THREADPOOL = new ThreadPoolExecutor(8, 8, 240L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    }
    
    private static final Map<String, ExecutorService> poolMap = new ConcurrentHashMap<String, ExecutorService>();
    
    
    private ThreadPoolUtil() throws Exception {
        throw new Exception();
    }
    
    public static ExecutorService getDefaultThreadPool() {
        return DEF_THREADPOOL;
    }
    
    public static ExecutorService customThreadPool(String poolName, int poolSize, long keepAliveTime) {
        if (null == poolName) {
            poolName = "default";
        }
        destructionPool(poolName);
        ExecutorService myNewPool = new ThreadPoolExecutor(poolSize, poolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        poolMap.put(poolName, myNewPool);
        return myNewPool;
    }
    
    public static ExecutorService customThreadPoolTo(String poolName, int poolSize, long keepAliveTime, boolean shutDown) {
        if (null == poolName) {
            poolName = "default";
        }
        ExecutorService myOldPool = poolMap.get(poolName);
        if (null != myOldPool) {
            return myOldPool;
        }
        ExecutorService myNewPool = new ThreadPoolExecutor(poolSize, poolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        poolMap.put(poolName, myNewPool);
        return myNewPool;
    }
    
    public static ExecutorService getPoolExecutor(String poolName) {
        return poolMap.get(poolName);
    }
    
    public static ExecutorService getPoolExecutorForNull(String poolName) {
        if (getPoolExecutor(poolName) == null) {
            ExecutorService pool = new ThreadPoolExecutor(4, 6, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
            poolMap.put(poolName, pool);
            return pool;
        }
        return getPoolExecutor(poolName);
    }
    
    public static void destructionPool(String poolName) {
        ExecutorService myOldPool = poolMap.get(poolName);
        if (null != myOldPool) {
            myOldPool.shutdown();
        }
    }
    
    public static void destructionPoolNow(String poolName) {
        ExecutorService myOldPool = poolMap.get(poolName);
        if (null != myOldPool) {
            myOldPool.shutdownNow();
        }
    }
    
    public static int destructionAllPool() {
        Set<String> keySet = new HashSet<String>();
        for (Map.Entry<String, ExecutorService> pool : poolMap.entrySet()) {
            pool.getValue().shutdown();
            keySet.add(pool.getKey());
        }
        for (String key : keySet) {
            poolMap.remove(key);
        }
        return keySet.size();
    }
}
