禁止直接使用 new Thread()
创建线程(线程池除外),而需要使用统一的工具类在公用线程池执行后台操作。
线程池的优点
- 重用线程池里的线程,避免创建和销毁线程所带来的性能开销
- 有效控制最大并发数,避免造成线程间抢占系统资源而造成阻塞
- 提高线程可管理性,可以统一进行分配,调优和监控的能力
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;
}
}