Android使用统一的工具类在公用线程池执行后台操作

禁止直接使用 new Thread() 创建线程(线程池除外),而需要使用统一的工具类在公用线程池执行后台操作。

线程池的优点

  1. 重用线程池里的线程,避免创建和销毁线程所带来的性能开销
  2. 有效控制最大并发数,避免造成线程间抢占系统资源而造成阻塞
  3. 提高线程可管理性,可以统一进行分配,调优和监控的能力

Android中的线程池

复用Java中的Executor接口,具体实现类为ThreadPoolExecutor,它有以下几个参数:
corePoolSize
线程池中核心线程数量。(一直存活,即使处于闲置状态)
maximumPoolSize
最大能创建的线程数量。非核心线程,包含核心线程个数。(达到这个值后,后续任务会阻塞)
keepAliveTime
非核心线程最大存活时间。(当设置allowCoreThreadTimeOut=true 同样会做用于核心线程,但通常不会这么做)
unit
keepAliveTime的时间单位。(TimeUnit中的枚举(时间单位))
workQueue
等待队列。execute 方法提交的Runnable存储在其中。(如果线程池中的线程数量大于等于corePoolSize的时候,把该任务放入等待队列)
threadFactory
线程创建工厂,用来创建线程的。(默认使用Executors.defaultThreadFactory() 来创建线程,线程具有相同的NORM_PRIORITY优先级并且是非守护线程)
handler
线程池的饱和拒绝策略(不常用)。(阻塞队列已且没有空闲的线程,此时继续提交任务,就需要采取一种策略处理该任务,默认会抛出异常)

常用与关键方法

void execute(Runnable run)//提交任务,交由线程池调度
void shutdown()//关闭线程池,等待任务执行完成
void shutdownNow()//关闭线程池,不等待任务执行完成
int getTaskCount()//返回线程池找中所有任务的数量 (已完成的任务+阻塞队列中的任务)
int getCompletedTaskCount()//返回线程池中已执行完成的任务数量 (已完成的任务)
int getPoolSize()//返回线程池中已创建线程数量
int getActiveCount()//返回当前正在运行的线程数量
void terminated()//线程池终止时执行的策略

例子一:

ThreadUtils .java  -->
public final class ThreadUtils {

    private static final Handler HANDLER = new Handler(Looper.getMainLooper());

    private static final Map> TYPE_PRIORITY_POOLS = new HashMap<>();

    private static final Map TASK_POOL_MAP = new ConcurrentHashMap<>();

    private static final int   CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final Timer TIMER     = new Timer();

    private static final byte TYPE_SINGLE = -1;
    private static final byte TYPE_CACHED = -2;
    private static final byte TYPE_IO     = -4;
    private static final byte TYPE_CPU    = -8;

    private static Executor sDeliver;

    /**
     * Return whether the thread is the main thread.
     *
     * @return {@code true}: yes
{@code false}: no */ public static boolean isMainThread() { return Looper.myLooper() == Looper.getMainLooper(); } public static Handler getMainHandler() { return HANDLER; } public static void runOnUiThread(final Runnable runnable) { if (Looper.myLooper() == Looper.getMainLooper()) { runnable.run(); } else { HANDLER.post(runnable); } } public static void runOnUiThreadDelayed(final Runnable runnable, long delayMillis) { HANDLER.postDelayed(runnable, delayMillis); } /** * Return a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue, using the provided * ThreadFactory to create new threads when needed. * * @param size The size of thread in the pool. * @return a fixed thread pool */ public static ExecutorService getFixedPool(@IntRange(from = 1) final int size) { return getPoolByTypeAndPriority(size); } /** * Return a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue, using the provided * ThreadFactory to create new threads when needed. * * @param size The size of thread in the pool. * @param priority The priority of thread in the poll. * @return a fixed thread pool */ public static ExecutorService getFixedPool(@IntRange(from = 1) final int size, @IntRange(from = 1, to = 10) final int priority) { return getPoolByTypeAndPriority(size, priority); } /** * Return a thread pool that uses a single worker thread operating * off an unbounded queue, and uses the provided ThreadFactory to * create a new thread when needed. * * @return a single thread pool */ public static ExecutorService getSinglePool() { return getPoolByTypeAndPriority(TYPE_SINGLE); } /** * Return a thread pool that uses a single worker thread operating * off an unbounded queue, and uses the provided ThreadFactory to * create a new thread when needed. * * @param priority The priority of thread in the poll. * @return a single thread pool */ public static ExecutorService getSinglePool(@IntRange(from = 1, to = 10) final int priority) { return getPoolByTypeAndPriority(TYPE_SINGLE, priority); } /** * Return a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. * * @return a cached thread pool */ public static ExecutorService getCachedPool() { return getPoolByTypeAndPriority(TYPE_CACHED); } /** * Return a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. * * @param priority The priority of thread in the poll. * @return a cached thread pool */ public static ExecutorService getCachedPool(@IntRange(from = 1, to = 10) final int priority) { return getPoolByTypeAndPriority(TYPE_CACHED, priority); } /** * Return a thread pool that creates (2 * CPU_COUNT + 1) threads * operating off a queue which size is 128. * * @return a IO thread pool */ public static ExecutorService getIoPool() { return getPoolByTypeAndPriority(TYPE_IO); } /** * Return a thread pool that creates (2 * CPU_COUNT + 1) threads * operating off a queue which size is 128. * * @param priority The priority of thread in the poll. * @return a IO thread pool */ public static ExecutorService getIoPool(@IntRange(from = 1, to = 10) final int priority) { return getPoolByTypeAndPriority(TYPE_IO, priority); } /** * Return a thread pool that creates (CPU_COUNT + 1) threads * operating off a queue which size is 128 and the maximum * number of threads equals (2 * CPU_COUNT + 1). * * @return a cpu thread pool for */ public static ExecutorService getCpuPool() { return getPoolByTypeAndPriority(TYPE_CPU); } /** * Return a thread pool that creates (CPU_COUNT + 1) threads * operating off a queue which size is 128 and the maximum * number of threads equals (2 * CPU_COUNT + 1). * * @param priority The priority of thread in the poll. * @return a cpu thread pool for */ public static ExecutorService getCpuPool(@IntRange(from = 1, to = 10) final int priority) { return getPoolByTypeAndPriority(TYPE_CPU, priority); } /** * Executes the given task in a fixed thread pool. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param The type of the task's result. */ public static void executeByFixed(@IntRange(from = 1) final int size, final Task task) { execute(getPoolByTypeAndPriority(size), task); } /** * Executes the given task in a fixed thread pool. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByFixed(@IntRange(from = 1) final int size, final Task task, @IntRange(from = 1, to = 10) final int priority) { execute(getPoolByTypeAndPriority(size, priority), task); } /** * Executes the given task in a fixed thread pool after the given delay. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeByFixedWithDelay(@IntRange(from = 1) final int size, final Task task, final long delay, final TimeUnit unit) { executeWithDelay(getPoolByTypeAndPriority(size), task, delay, unit); } /** * Executes the given task in a fixed thread pool after the given delay. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByFixedWithDelay(@IntRange(from = 1) final int size, final Task task, final long delay, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeWithDelay(getPoolByTypeAndPriority(size, priority), task, delay, unit); } /** * Executes the given task in a fixed thread pool at fix rate. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeByFixedAtFixRate(@IntRange(from = 1) final int size, final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(size), task, 0, period, unit); } /** * Executes the given task in a fixed thread pool at fix rate. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByFixedAtFixRate(@IntRange(from = 1) final int size, final Task task, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(size, priority), task, 0, period, unit); } /** * Executes the given task in a fixed thread pool at fix rate. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeByFixedAtFixRate(@IntRange(from = 1) final int size, final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(size), task, initialDelay, period, unit); } /** * Executes the given task in a fixed thread pool at fix rate. * * @param size The size of thread in the fixed thread pool. * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByFixedAtFixRate(@IntRange(from = 1) final int size, final Task task, long initialDelay, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(size, priority), task, initialDelay, period, unit); } /** * Executes the given task in a single thread pool. * * @param task The task to execute. * @param The type of the task's result. */ public static void executeBySingle(final Task task) { execute(getPoolByTypeAndPriority(TYPE_SINGLE), task); } /** * Executes the given task in a single thread pool. * * @param task The task to execute. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeBySingle(final Task task, @IntRange(from = 1, to = 10) final int priority) { execute(getPoolByTypeAndPriority(TYPE_SINGLE, priority), task); } /** * Executes the given task in a single thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeBySingleWithDelay(final Task task, final long delay, final TimeUnit unit) { executeWithDelay(getPoolByTypeAndPriority(TYPE_SINGLE), task, delay, unit); } /** * Executes the given task in a single thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeBySingleWithDelay(final Task task, final long delay, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeWithDelay(getPoolByTypeAndPriority(TYPE_SINGLE, priority), task, delay, unit); } /** * Executes the given task in a single thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeBySingleAtFixRate(final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_SINGLE), task, 0, period, unit); } /** * Executes the given task in a single thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeBySingleAtFixRate(final Task task, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_SINGLE, priority), task, 0, period, unit); } /** * Executes the given task in a single thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeBySingleAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_SINGLE), task, initialDelay, period, unit); } /** * Executes the given task in a single thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeBySingleAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate( getPoolByTypeAndPriority(TYPE_SINGLE, priority), task, initialDelay, period, unit ); } /** * Executes the given task in a cached thread pool. * * @param task The task to execute. * @param The type of the task's result. */ public static void executeByCached(final Task task) { execute(getPoolByTypeAndPriority(TYPE_CACHED), task); } /** * Executes the given task in a cached thread pool. * * @param task The task to execute. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCached(final Task task, @IntRange(from = 1, to = 10) final int priority) { execute(getPoolByTypeAndPriority(TYPE_CACHED, priority), task); } /** * Executes the given task in a cached thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeByCachedWithDelay(final Task task, final long delay, final TimeUnit unit) { executeWithDelay(getPoolByTypeAndPriority(TYPE_CACHED), task, delay, unit); } /** * Executes the given task in a cached thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCachedWithDelay(final Task task, final long delay, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeWithDelay(getPoolByTypeAndPriority(TYPE_CACHED, priority), task, delay, unit); } /** * Executes the given task in a cached thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeByCachedAtFixRate(final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CACHED), task, 0, period, unit); } /** * Executes the given task in a cached thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCachedAtFixRate(final Task task, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CACHED, priority), task, 0, period, unit); } /** * Executes the given task in a cached thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeByCachedAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CACHED), task, initialDelay, period, unit); } /** * Executes the given task in a cached thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCachedAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate( getPoolByTypeAndPriority(TYPE_CACHED, priority), task, initialDelay, period, unit ); } /** * Executes the given task in an IO thread pool. * * @param task The task to execute. * @param The type of the task's result. */ public static void executeByIo(final Task task) { execute(getPoolByTypeAndPriority(TYPE_IO), task); } /** * Executes the given task in an IO thread pool. * * @param task The task to execute. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByIo(final Task task, @IntRange(from = 1, to = 10) final int priority) { execute(getPoolByTypeAndPriority(TYPE_IO, priority), task); } /** * Executes the given task in an IO thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeByIoWithDelay(final Task task, final long delay, final TimeUnit unit) { executeWithDelay(getPoolByTypeAndPriority(TYPE_IO), task, delay, unit); } /** * Executes the given task in an IO thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByIoWithDelay(final Task task, final long delay, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeWithDelay(getPoolByTypeAndPriority(TYPE_IO, priority), task, delay, unit); } /** * Executes the given task in an IO thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeByIoAtFixRate(final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_IO), task, 0, period, unit); } /** * Executes the given task in an IO thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByIoAtFixRate(final Task task, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_IO, priority), task, 0, period, unit); } /** * Executes the given task in an IO thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeByIoAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_IO), task, initialDelay, period, unit); } /** * Executes the given task in an IO thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByIoAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate( getPoolByTypeAndPriority(TYPE_IO, priority), task, initialDelay, period, unit ); } /** * Executes the given task in a cpu thread pool. * * @param task The task to execute. * @param The type of the task's result. */ public static void executeByCpu(final Task task) { execute(getPoolByTypeAndPriority(TYPE_CPU), task); } /** * Executes the given task in a cpu thread pool. * * @param task The task to execute. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCpu(final Task task, @IntRange(from = 1, to = 10) final int priority) { execute(getPoolByTypeAndPriority(TYPE_CPU, priority), task); } /** * Executes the given task in a cpu thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeByCpuWithDelay(final Task task, final long delay, final TimeUnit unit) { executeWithDelay(getPoolByTypeAndPriority(TYPE_CPU), task, delay, unit); } /** * Executes the given task in a cpu thread pool after the given delay. * * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCpuWithDelay(final Task task, final long delay, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeWithDelay(getPoolByTypeAndPriority(TYPE_CPU, priority), task, delay, unit); } /** * Executes the given task in a cpu thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeByCpuAtFixRate(final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CPU), task, 0, period, unit); } /** * Executes the given task in a cpu thread pool at fix rate. * * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCpuAtFixRate(final Task task, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CPU, priority), task, 0, period, unit); } /** * Executes the given task in a cpu thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeByCpuAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(getPoolByTypeAndPriority(TYPE_CPU), task, initialDelay, period, unit); } /** * Executes the given task in a cpu thread pool at fix rate. * * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param priority The priority of thread in the poll. * @param The type of the task's result. */ public static void executeByCpuAtFixRate(final Task task, long initialDelay, final long period, final TimeUnit unit, @IntRange(from = 1, to = 10) final int priority) { executeAtFixedRate( getPoolByTypeAndPriority(TYPE_CPU, priority), task, initialDelay, period, unit ); } /** * Executes the given task in a custom thread pool. * * @param pool The custom thread pool. * @param task The task to execute. * @param The type of the task's result. */ public static void executeByCustom(final ExecutorService pool, final Task task) { execute(pool, task); } /** * Executes the given task in a custom thread pool after the given delay. * * @param pool The custom thread pool. * @param task The task to execute. * @param delay The time from now to delay execution. * @param unit The time unit of the delay parameter. * @param The type of the task's result. */ public static void executeByCustomWithDelay(final ExecutorService pool, final Task task, final long delay, final TimeUnit unit) { executeWithDelay(pool, task, delay, unit); } /** * Executes the given task in a custom thread pool at fix rate. * * @param pool The custom thread pool. * @param task The task to execute. * @param period The period between successive executions. * @param unit The time unit of the period parameter. * @param The type of the task's result. */ public static void executeByCustomAtFixRate(final ExecutorService pool, final Task task, final long period, final TimeUnit unit) { executeAtFixedRate(pool, task, 0, period, unit); } /** * Executes the given task in a custom thread pool at fix rate. * * @param pool The custom thread pool. * @param task The task to execute. * @param initialDelay The time to delay first execution. * @param period The period between successive executions. * @param unit The time unit of the initialDelay and period parameters. * @param The type of the task's result. */ public static void executeByCustomAtFixRate(final ExecutorService pool, final Task task, long initialDelay, final long period, final TimeUnit unit) { executeAtFixedRate(pool, task, initialDelay, period, unit); } /** * Cancel the given task. * * @param task The task to cancel. */ public static void cancel(final Task task) { if (task == null) return; task.cancel(); } /** * Cancel the given tasks. * * @param tasks The tasks to cancel. */ public static void cancel(final Task... tasks) { if (tasks == null || tasks.length == 0) return; for (Task task : tasks) { if (task == null) continue; task.cancel(); } } /** * Cancel the given tasks. * * @param tasks The tasks to cancel. */ public static void cancel(final List tasks) { if (tasks == null || tasks.size() == 0) return; for (Task task : tasks) { if (task == null) continue; task.cancel(); } } /** * Cancel the tasks in pool. * * @param executorService The pool. */ public static void cancel(ExecutorService executorService) { if (executorService instanceof ThreadPoolExecutor4Util) { for (Map.Entry taskTaskInfoEntry : TASK_POOL_MAP.entrySet()) { if (taskTaskInfoEntry.getValue() == executorService) { cancel(taskTaskInfoEntry.getKey()); } } } else { Log.e("ThreadUtils", "The executorService is not ThreadUtils's pool."); } } /** * Set the deliver. * * @param deliver The deliver. */ public static void setDeliver(final Executor deliver) { sDeliver = deliver; } private static void execute(final ExecutorService pool, final Task task) { execute(pool, task, 0, 0, null); } private static void executeWithDelay(final ExecutorService pool, final Task task, final long delay, final TimeUnit unit) { execute(pool, task, delay, 0, unit); } private static void executeAtFixedRate(final ExecutorService pool, final Task task, long delay, final long period, final TimeUnit unit) { execute(pool, task, delay, period, unit); } private static void execute(final ExecutorService pool, final Task task, long delay, final long period, final TimeUnit unit) { synchronized (TASK_POOL_MAP) { if (TASK_POOL_MAP.get(task) != null) { Log.e("ThreadUtils", "Task can only be executed once."); return; } TASK_POOL_MAP.put(task, pool); } if (period == 0) { if (delay == 0) { pool.execute(task); } else { TimerTask timerTask = new TimerTask() { @Override public void run() { pool.execute(task); } }; TIMER.schedule(timerTask, unit.toMillis(delay)); } } else { task.setSchedule(true); TimerTask timerTask = new TimerTask() { @Override public void run() { pool.execute(task); } }; TIMER.scheduleAtFixedRate(timerTask, unit.toMillis(delay), unit.toMillis(period)); } } private static ExecutorService getPoolByTypeAndPriority(final int type) { return getPoolByTypeAndPriority(type, Thread.NORM_PRIORITY); } private static ExecutorService getPoolByTypeAndPriority(final int type, final int priority) { synchronized (TYPE_PRIORITY_POOLS) { ExecutorService pool; Map priorityPools = TYPE_PRIORITY_POOLS.get(type); if (priorityPools == null) { priorityPools = new ConcurrentHashMap<>(); pool = ThreadPoolExecutor4Util.createPool(type, priority); priorityPools.put(priority, pool); TYPE_PRIORITY_POOLS.put(type, priorityPools); } else { pool = priorityPools.get(priority); if (pool == null) { pool = ThreadPoolExecutor4Util.createPool(type, priority); priorityPools.put(priority, pool); } } return pool; } } static final class ThreadPoolExecutor4Util extends ThreadPoolExecutor { private static ExecutorService createPool(final int type, final int priority) { switch (type) { case TYPE_SINGLE: return new ThreadPoolExecutor4Util(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue4Util(), new UtilsThreadFactory("single", priority) ); case TYPE_CACHED: return new ThreadPoolExecutor4Util(0, 128, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue4Util(true), new UtilsThreadFactory("cached", priority) ); case TYPE_IO: return new ThreadPoolExecutor4Util(2 * CPU_COUNT + 1, 2 * CPU_COUNT + 1, 30, TimeUnit.SECONDS, new LinkedBlockingQueue4Util(), new UtilsThreadFactory("io", priority) ); case TYPE_CPU: return new ThreadPoolExecutor4Util(CPU_COUNT + 1, 2 * CPU_COUNT + 1, 30, TimeUnit.SECONDS, new LinkedBlockingQueue4Util(true), new UtilsThreadFactory("cpu", priority) ); default: return new ThreadPoolExecutor4Util(type, type, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue4Util(), new UtilsThreadFactory("fixed(" + type + ")", priority) ); } } private final AtomicInteger mSubmittedCount = new AtomicInteger(); private LinkedBlockingQueue4Util mWorkQueue; ThreadPoolExecutor4Util(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, LinkedBlockingQueue4Util workQueue, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory ); workQueue.mPool = this; mWorkQueue = workQueue; } private int getSubmittedCount() { return mSubmittedCount.get(); } @Override protected void afterExecute(Runnable r, Throwable t) { mSubmittedCount.decrementAndGet(); super.afterExecute(r, t); } @Override public void execute(@NonNull Runnable command) { if (this.isShutdown()) return; mSubmittedCount.incrementAndGet(); try { super.execute(command); } catch (RejectedExecutionException ignore) { Log.e("ThreadUtils", "This will not happen!"); mWorkQueue.offer(command); } catch (Throwable t) { mSubmittedCount.decrementAndGet(); } } } private static final class LinkedBlockingQueue4Util extends LinkedBlockingQueue { private volatile ThreadPoolExecutor4Util mPool; private int mCapacity = Integer.MAX_VALUE; LinkedBlockingQueue4Util() { super(); } LinkedBlockingQueue4Util(boolean isAddSubThreadFirstThenAddQueue) { super(); if (isAddSubThreadFirstThenAddQueue) { mCapacity = 0; } } LinkedBlockingQueue4Util(int capacity) { super(); mCapacity = capacity; } @Override public boolean offer(@NonNull Runnable runnable) { if (mCapacity <= size() && mPool != null && mPool.getPoolSize() < mPool.getMaximumPoolSize()) { // create a non-core thread return false; } return super.offer(runnable); } } static final class UtilsThreadFactory extends AtomicLong implements ThreadFactory { private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1); private static final long serialVersionUID = -9209200509960368598L; private final String namePrefix; private final int priority; private final boolean isDaemon; UtilsThreadFactory(String prefix, int priority) { this(prefix, priority, false); } UtilsThreadFactory(String prefix, int priority, boolean isDaemon) { namePrefix = prefix + "-pool-" + POOL_NUMBER.getAndIncrement() + "-thread-"; this.priority = priority; this.isDaemon = isDaemon; } @Override public Thread newThread(@NonNull Runnable r) { Thread t = new Thread(r, namePrefix + getAndIncrement()) { @Override public void run() { try { super.run(); } catch (Throwable t) { Log.e("ThreadUtils", "Request threw uncaught throwable", t); } } }; t.setDaemon(isDaemon); t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println(e); } }); t.setPriority(priority); return t; } } public abstract static class SimpleTask extends Task { @Override public void onCancel() { Log.e("ThreadUtils", "onCancel: " + Thread.currentThread()); } @Override public void onFail(Throwable t) { Log.e("ThreadUtils", "onFail: ", t); } } public abstract static class Task implements Runnable { private static final int NEW = 0; private static final int RUNNING = 1; private static final int EXCEPTIONAL = 2; private static final int COMPLETING = 3; private static final int CANCELLED = 4; private static final int INTERRUPTED = 5; private static final int TIMEOUT = 6; private final AtomicInteger state = new AtomicInteger(NEW); private volatile boolean isSchedule; private volatile Thread runner; private Timer mTimer; private long mTimeoutMillis; private OnTimeoutListener mTimeoutListener; private Executor deliver; public abstract T doInBackground() throws Throwable; public abstract void onSuccess(T result); public abstract void onCancel(); public abstract void onFail(Throwable t); @Override public void run() { if (isSchedule) { if (runner == null) { if (!state.compareAndSet(NEW, RUNNING)) return; runner = Thread.currentThread(); if (mTimeoutListener != null) { Log.w("ThreadUtils", "Scheduled task doesn't support timeout."); } } else { if (state.get() != RUNNING) return; } } else { if (!state.compareAndSet(NEW, RUNNING)) return; runner = Thread.currentThread(); if (mTimeoutListener != null) { mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { if (!isDone() && mTimeoutListener != null) { timeout(); mTimeoutListener.onTimeout(); onDone(); } } }, mTimeoutMillis); } } try { final T result = doInBackground(); if (isSchedule) { if (state.get() != RUNNING) return; getDeliver().execute(new Runnable() { @Override public void run() { onSuccess(result); } }); } else { if (!state.compareAndSet(RUNNING, COMPLETING)) return; getDeliver().execute(new Runnable() { @Override public void run() { onSuccess(result); onDone(); } }); } } catch (InterruptedException ignore) { state.compareAndSet(CANCELLED, INTERRUPTED); } catch (final Throwable throwable) { if (!state.compareAndSet(RUNNING, EXCEPTIONAL)) return; getDeliver().execute(new Runnable() { @Override public void run() { onFail(throwable); onDone(); } }); } } public void cancel() { cancel(true); } public void cancel(boolean mayInterruptIfRunning) { synchronized (state) { if (state.get() > RUNNING) return; state.set(CANCELLED); } if (mayInterruptIfRunning) { if (runner != null) { runner.interrupt(); } } getDeliver().execute(new Runnable() { @Override public void run() { onCancel(); onDone(); } }); } private void timeout() { synchronized (state) { if (state.get() > RUNNING) return; state.set(TIMEOUT); } if (runner != null) { runner.interrupt(); } } public boolean isCanceled() { return state.get() >= CANCELLED; } public boolean isDone() { return state.get() > RUNNING; } public Task setDeliver(Executor deliver) { this.deliver = deliver; return this; } /** * Scheduled task doesn't support timeout. */ public Task setTimeout(final long timeoutMillis, final OnTimeoutListener listener) { mTimeoutMillis = timeoutMillis; mTimeoutListener = listener; return this; } private void setSchedule(boolean isSchedule) { this.isSchedule = isSchedule; } private Executor getDeliver() { if (deliver == null) { return getGlobalDeliver(); } return deliver; } @CallSuper protected void onDone() { TASK_POOL_MAP.remove(this); if (mTimer != null) { mTimer.cancel(); mTimer = null; mTimeoutListener = null; } } public interface OnTimeoutListener { void onTimeout(); } } public static class SyncValue { private CountDownLatch mLatch = new CountDownLatch(1); private AtomicBoolean mFlag = new AtomicBoolean(); private T mValue; public void setValue(T value) { if (mFlag.compareAndSet(false, true)) { mValue = value; mLatch.countDown(); } } public T getValue() { if (!mFlag.get()) { try { mLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } return mValue; } public T getValue(long timeout, TimeUnit unit, T defaultValue) { if (!mFlag.get()) { try { mLatch.await(timeout, unit); } catch (InterruptedException e) { e.printStackTrace(); return defaultValue; } } return mValue; } } private static Executor getGlobalDeliver() { if (sDeliver == null) { sDeliver = new Executor() { @Override public void execute(@NonNull Runnable command) { runOnUiThread(command); } }; } return sDeliver; } }

例子二:

ThreadPoolUtils.java -->
package com.youkagames.gameplatform.support.utils;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolUtils {
    public static volatile ThreadPoolExecutor pool = null;


    private final static int CORE_POOL_SIZE = 10;//核心线程数
    private final static int MAXIMUM_POOL_SIZE = 50;//最大线程数
    private final static long KEEP_ALIVE_TIME = 5;//非核心线程空闲时间
    private final static int MAXIMUM_WORK_QUEUE = 400;//消息队列最大任务数

    private ThreadPoolUtils() {
        pool = new ThreadPoolExecutor(CORE_POOL_SIZE,// 1. 核心线程数
                MAXIMUM_POOL_SIZE,// 2. 最大线程数
                KEEP_ALIVE_TIME, // 3. 非核心线程空闲时间
                TimeUnit.SECONDS, // 4. 时间单位
                new ArrayBlockingQueue<>(MAXIMUM_WORK_QUEUE),// 5. 阻塞队列
                Executors.defaultThreadFactory(),// 6. 创建线程工厂
                new ThreadPoolExecutor.AbortPolicy());// 7. 拒绝策略
        LogUtil.e("xulei", "PushThreadPoolUtils 线程池创建完成");
    }

    public static ThreadPoolExecutor getInstance() {
        //双重if单例
        if (null == pool) {
            synchronized (ThreadPoolUtils.class) {
                if (pool == null) {
                    new ThreadPoolUtils();
                    return pool;
                }
            }
        }
        return pool;
    }

    // 无响应执行
    public static void execute(Runnable runnable) {
        getInstance().execute(runnable);
    }

    // 有响应执行
    public static  Future submit(Callable callable) {
        return getInstance().submit(callable);
    }

}

例子三:

ThreadHelper.java  -->
public final class ThreadHelper {
    public static final ThreadHelper INST = new ThreadHelper();

    private ExecutorService executors;

    private ThreadHelper(){
    }

    /**
     * 在线程中执行
     * @param runnable 要执行的runnable
     */
    public void execute(Runnable runnable) {
        ExecutorService executorService = getExecutorService();
        if (executorService != null) {
            executorService.execute(runnable);
        } else {
            new Thread(runnable).start();
        }
    }

    /**
     * 获取缓存线程池
     * @return 缓存线程池服务
     */
    private ExecutorService getExecutorService(){
        if (executors == null) {
            executors = Executors.newCachedThreadPool();
        }

        return executors;
    }
}

你可能感兴趣的:(Android使用统一的工具类在公用线程池执行后台操作)