Android App的开发中,经常需要用到线程。执行网络操作、进行数据库查找等异步操作。线程池的使用可以更方便的使用线程,记录一下对线程池的一些理解。
1、为什么要用线程池?
线程池有什么优点,在《Android开发艺术探索》这本书上面是这样写的:
1.1、重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销;
1.2、能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象;
1.3、能够对线程进行简单的管理,并提供定时执行以及在指定间隔循环执行等功能。
2、熟悉几个概念
Executor是一个接口,线程池的实现类是ThreadPoolExecutor。ThreadPoolExecutor的构造方法里面的参数:
public ThreadPoolExecutor (
int corePoolSize,
int maxmumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable runnable> workQueue,
ThreadFactory threadFactory)
2.1、corePoolSize
核心线程数,会在线程池里面一直存活的线程,也就是能够及时快速响应任务的执行。但可以通过设置allowCoreThreadTimeOut设置为闲置等待keepAliveTime而终止。
2.2、maxmumPoolSize
最大线程数,超过最大线程数的任务会被阻塞。
2.3、keepAliveTime、unit
非核心线程闲置的超时时间,allowCoreThreadTimeOut = true后,对核心线程也同样起作用。
2.4、workQueue
通过execute()方法提交的runnable都会添加到该任务队列中。
2.5、threadFactiry
线程工厂,为线程池提供线程,可以实现指定设置的线程。
随着任务的增多,线程池会首先考虑核心线程,再考虑插入任务队列、非核心线程,再考虑线程池最大线程数,然后拒绝执行任务。
3、线程池的分类
3.1、FixedThreadPool
只有数量固定的核心线程,并且没有超时机制,任务队列没有大小限制。快速响应外界的请求。
3.2、CachedThreadPool
只有非核心线程,线程数为Integer.MAX_VALUE,闲置线程超时时长为60秒,任务队列为空集合,任何任务都会立即执行,适合大量耗时较少的任务。整个线程池也可能处于闲置状态,几乎不占用系统资源。
3.3、ScheduledThreadPool
核心线程数固定,非核心线程数没有限制,闲置时会被立即回收,执行定时任务和具有固定周期的循环任务。
3.4、SingleTheadExecutor
只有一个核心线程,所有任务都会在同一个线程中按顺序执行,任务之间不需要处理线程同步的问题。
4、注意事项
线程池的关闭,threadPool.submit()
调用后,如果再往线程池中添加任务,就会抛异常,thread = 0
如果只是想要终止该任务,可以使用以下方式:
FutureTask.cancel(true);
关于Future、FutureTask可以参考:新手浅谈Future