1. Android中的线程池有哪些,它们的区别是什么?
ThreadPoolExecutor是线程池的真正实现,看一下它的构造方法
public ThreadPoolExecutor(
// 核心线程数,会一直存活,除非设置了allowCoreThreadTimeOut为true
int corePoolSize,
// 最大线程数,活动线程达到这个数,后续任务被阻塞
int maximumPoolSize,
// 非核心线程闲置的超时时长,当allowCoreThreadTimeOut为true也会作用于核心线程
long keepAliveTime,
// keepAliveTime的时间单位
TimeUnit unit,
// 任务队列,存储执行的Runnable
BlockingQueue<Runnable> workQueue,
// 线程工厂,创建新线程
ThreadFactory threadFactory,
// 当任务队列已满或者无法执行新任务时,会调用handler的rejectedExecution通知调用者
// 默认情况下直接抛出RejectedExecutionException
RejectedExecutionHandler handler) {
...
}
线程池的分类:
- FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
它是一种线程数量固定的线程池,当线程处于空闲状态也不会被回收,当所有的线程都处于活动状态时,新任务会处于等待状态,直到有线程空闲出来。由于FixedThreadPool只有核心线程并且这些线程不会被回收,所以能够更快速的响应外界请求。
- CachedThreadPool
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
它是线程数量不定的线程池,只有非核心线程,最大线程数为Integer.MAX_VALUE,当线程池中的线程都处于活动状态时,线程池会创建新的线程来执行新任务,否则就会利用空闲的线程执行。线程池中的空闲线程都有超时机制,超时时长为60s。由于SynchronousQueue无法插入任务,所以任何任务都会立刻执行。CachedThreadPool适合执行大量的耗时较少的任务。
- ScheduledThreadPool
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
它的核心线程数量固定,非核心线程数量没有限制,当非核心线程闲置时会被立即回收。主要用于执行定时任务和具有固定周期的重复任务。
- SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
它只有一个核心线程,确保了所有的任务在同一个线程中按顺序执行。
2. 为什么要使用线程池?
- 重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销。
- 能有效控制线程的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象。
- 能够对线程进行简单的管理,提供定时执行以及指定间隔循环执行等功能。
网友评论