package com.common.lib_base.common.async;

import android.os.Process;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Date: 2022/5/17 0017 10:22
 * Description:
 */
public class ThreadPoolManager {

    // CPU核心数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    /**
     * 核心线程数
     * -1 是考虑到某一个核心线程数出现意外不可用
     * Math.max保证最少核心线程数有2个
     */
    private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//    private static final int CORE_POOL_SIZE =  CPU_COUNT + 1;
    /**
     * 最大线程数
     * 理论上来说不需要+1或者-1,一个核心对应一个线程最好，但是实际上会有种种原因导致核心的利用不是那么完全，比如有任务被挂起，那这个核心就会空闲下来，所以设置+1，是为了提高核心的利用率
     * 如果设置成-1会怎么样，假如只有一个核心呢？那-1就成0了，很显然无论如何也不应该-1
     */
    private static final int MAX_POOL_SIZE = CPU_COUNT * 2 + 1;
    // 阻塞任务队列容量
    private static final int QUEUE_CAPACITY = 64;
    // 等待时间
    private static final int KEEP_ALIVE_TIME = 30;

    // CPU型线程池
    private ThreadPoolExecutor cpuExecutor = new ThreadPoolExecutor(
            CPU_COUNT,
            CPU_COUNT,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(QUEUE_CAPACITY),
            mThreadFactory);

    // IO型线程池
    private ThreadPoolExecutor iOExecutor = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(QUEUE_CAPACITY),
            mThreadFactory);

    // 线程工厂
    private static final ThreadFactory mThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            // 设置线程名字
            Thread thread = new Thread(r, "ThreadPoolManager #" + mCount.getAndIncrement());
            // 设置线程优先级
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            return thread;
        }
    };


    /**
     * 单例设计模式（饿汉式）
     * 单例首先私有化构造方法，然后饿汉式一开始就开始创建，并提供get方法
     */
    private static ThreadPoolManager mInstance = new ThreadPoolManager();

    public static ThreadPoolManager getInstance() {
        return mInstance;
    }

    /**
     * 执行IO任务
     */
    public void executeIOTask(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        iOExecutor.execute(runnable);
    }

    /**
     * 移除IO任务
     */
    public void removeIOTask(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        iOExecutor.remove(runnable);
    }

    /**
     * 执行CPU任务
     */
    public void executeCpuTask(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        cpuExecutor.execute(runnable);
    }

    /**
     * 移除CPU任务
     */
    public void removeCpuTask(Runnable runnable) {
        if (runnable == null) {
            return;
        }
        cpuExecutor.remove(runnable);
    }

    /**
     * 停止线程池
     */
    public void shutdownExecutor() {
        if (cpuExecutor != null) {
            cpuExecutor.shutdown();
        }
        if (iOExecutor != null) {
            iOExecutor.shutdown();
        }
    }

}

