Android下线程池的对应实现对象是ThreadPoolExecutor这个类,它的构造参数配置如下:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
throw new RuntimeException("Stub!");
}
参数说明
- int corePoolSize : 线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的线程会在新任务到来时会有超时策略,这个时间间隔由keepAliveTime指定,当等待时间超过keepAliveTime之后,核心线程会终止。
- int maximunPoolSize : 线程池容纳的最大线程数,超过这个数量后,新任务会被阻塞
- long keepAliveTiem : 非核心线程闲置时的超时时长,超过这个时长,线程被收回。在allowCoreThreadTimeOut属性为true时候,同样作用于核心线程。
- TimeUnit unit : 用于指定keepAliveTime的时间单位,枚举类,常用的有,MILLISECONDS(毫秒),SECONDS(秒),MINUTES(分钟)等
- BlockingQueue<Runnable> workQueue : 线程池中的任务队列,通过线程池的execute方法提交的Runnable对象存储在这个队列中。
- ThreadFactory threadFactory : 线程工厂,为线程池提供创建新线程的功能,它是一个接口,只有一个方法Thread newThread(Runnable r);
- RejectedExecutionHandler handler : 不常用,因为某些原因导致线程池无法执行新任务,可能是任务队列已满或者无法成功执行任务等,这个时候ThreadPoolExecutor会调用Handler的rejectExecution方法来通知调用者,通常就是抛出一个异常,默认异常是AbortPolicy ,还有CallerRunsPolicy,DiscardPolicy和DiscardOldestPolicy
它对应的执行任务和移除任务的方法分别是:execute(Runnable run) 和remove(Runnable run),那么自己搞一个线程池Demo出来应该就是这个样子的:
private int corePoolSize;
private int maximumPoolSize;
private int keepAliveTime = 1;
private TimeUnit unit = TimeUnit.HOURS;
private ThreadPoolExecutor executor;
private ThreadPoolExecutorManager(){
corePoolSize = Runtime.getRuntime().availableProcessors()*2 + 1;
maximumPoolSize = corePoolSize;
executor = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
new LinkedBlockingQueue<Runnable>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
/**
* 执行任务
* @param runnable
*/
public void execute(Runnable runnable){
if(runnable==null)return;
executor.execute(runnable);
}
/**
* 移除任务
*/
public void remove(Runnable runnable){
if(runnable==null)return;
executor.remove(runnable);
}
AsyncTask线程池默认的配置信息:
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); //核心线程数维持在2-4
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; //线程池最大数量CPU数量的2倍+1
private static final int KEEP_ALIVE_SECONDS = 30; //线程超时时间30秒
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
- //任务队列数量128
- private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
线程池的优点:
- 复用线程池中的线程,避免因为线程的创建和销毁带来性能开销
- 有效控制线程池的最大并发数,避免大量线程之间互相抢占系统资源而导致的阻塞现象
- 对线程进行简单的管理,提供定时执行以及指定间隔循环执行等功能
Android线程池的系统实现
- FixedThreadPool
线程池数量固定,当线程处于空闲状态的时候不会被回收,除非线程池关闭,所有线程都在活动状态的时候,新任务会等待。因为只有核心线程并且不会被回收,所以更加快速的响应。
public static ExecutorService getFixedThreadExecutor() {
ExecutorService executorService = Executors.newFixedThreadPool(5);
return executorService;
}
系统实现如下:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
- CachedThreadPool
没有核心线程,只有非核心线程,非核心线程数量无限大,每个线程超时时间为60秒,超时就会被回收,所以线程池中没有任务的时候,线程池几乎不占用资源, 每个新任务到来都会立即执行,有空闲线程就利用,没有空闲线程就新建。
public static ExecutorService getCachedThreadPool() {
ExecutorService executorService = Executors.newCachedThreadPool();
return executorService;
}
系统实现如下:
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
- ScheduledThreadPool
核心线程数量固定,非核心线程数量没有限制,非核心线程空闲时间默认10秒,常用于执行定时任务
public static ExecutorService getScheduledThreadPool() {
return Executors.newScheduledThreadPool(5);
}
系统实现:
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
用法特别来说:
ScheduledExecutorService scheduledThreadPool = LocalThreadPool.getScheduledThreadPool();
scheduledThreadPool.schedule(runnable,2000, TimeUnit.MILLISECONDS);//延时2秒后执行任务
scheduledThreadPool.scheduleAtFixedRate(runnable,100,1000,TimeUnit.MILLISECONDS);//延时100毫秒后,每1秒执行一次任务
- SingleThreadExecutor
只有一个核心线程,确保所有的任务在同一个线程中按顺序执行,意义在于统一所有的外界任务到一个线程中去
public static ExecutorService getSingleThreadExecutor() {
return Executors.newSingleThreadExecutor();
}
系统实现:
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
以上就是Android线程池的概述了,读者感兴趣可以跟进一些涉及到类的源码。
作者:player_android 发表于2017/1/12 18:19:36 原文链接
阅读:153 评论:0 查看评论