package com.efounder.chat.utils;

import android.os.Handler;

import java.util.LinkedList;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created by zhangshunyun on 2017/7/13.
 */

public class ThreadPoolUtils {

    private static final int POOLNUM = 3;// 线程池大小
    private volatile static int count = 0;// 工作线程数
    private static ThreadPoolExecutor THREADPOOL = (ThreadPoolExecutor) Executors.newFixedThreadPool(POOLNUM);// 线程池
    private static LinkedList<Task> TASKQUEUE = new LinkedList<>();// 等待队列
    private static Handler handler = new Handler();

    /**
     * 执行任务
     *
     * @param task
     * @return 是否执行，否：放入等待队列
     */
    public static boolean execute(Task task) {
        boolean isExecute = false;
        if (count < POOLNUM) {
            count++;
            isExecute = true;
            THREADPOOL.execute(task);
        } else {
            // 排队
            TASKQUEUE.addLast(task);
        }
        return isExecute;
    }

    /**
     * 删除等待任务
     *
     * @param id
     * @return
     */
    public static boolean cancelWaitTask(String id) {
        boolean isCancel = false;

        Task target = null;
        for (Task item : TASKQUEUE) {
            if (item.id == id) {
                target = item;
                break;
            }
        }
        if (target != null) {
            TASKQUEUE.remove(target);
            isCancel = true;
        }
        return isCancel;
    }

    /**
     * 线程池中执行的任务
     */
    public static abstract class Task implements Runnable {
        // 使用id去标识任务，当存在排队等待的任务时可以依据id进行删除操作。
        public String id;

        @Override
        public void run() {
            // 耗时工作
            work();
            // 完成任务后通知主线程，线程池有一个空余线程,并试图从等待队列中获取下载任务
            handler.post(new Runnable() {
                @Override
                public void run() {
                    count--;
                    Task first = TASKQUEUE.pollFirst();
                    if (first != null) {
                        execute(first);
                    }
                }
            });
        }

        protected abstract void work();
    }
}
