Andoid中使用线程池
- 在安卓app的开发过程中,不可避免的会遇到多线程场景,在某些对性能要求比较高的情景下,每次创建一个新线程执行任务,任务执行完成后再释放的这种方式并不是最优的,每次都新建、释放线程会消耗比较多的资源,实际上我们可以提前创建好一些线程,有任务来时从这些线程中拿一些出来执行,这样就可以避免大量无意义的线程创建和销毁。这即是我下面要说的线程模型。
线程池:Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序
都可以使用线程池。在开发过程中,合理地使用线程池能够带来3个好处:
1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
2. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
3. 提高线程的可管理性。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控。但是,要做到合理利用线程池,必须对其实现原理了如指掌。
Java中常用的线程池都是ThreadPoolExecutor不同的配置产生的以符合不同的场景.所以理解ThreadPoolExecutor至关重要.
下图是线程池的原理模型.
– Java中常见的线程池:
1. FixedThreadPoolExecutor
FixedThreadPool被称为可重用固定线程数的线程池。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
FixedThreadPoolExecutor是一种线程数量固定的线程池,当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭了.当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来.由于FixedThreadPool只有核心线程并且这些核心线程不会被回收,这意味着它能够更加快速的响应外界的请求.
- SingleThreadExecutor
SingleThreadExecutor是使用单个worker线程的Executor.
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
SingleThreadPool内部只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行.
CachedThreadPool
CachedThreadPool是一个会根据需要创建新线程的线程池。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
-
CachedThreadPool是一种线程数量不定的线程池,它只有非核心线程,并且其最大线程数Integer.MAX_VALUE是一个很大的数,实际上就相当于最大线程数可以任意大.当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务,否则就会利用空闲的线程来处理新任务.线程池中的空闲线程都有超时机制,60秒,超过60秒的的闲置线程就会被回收.
CachedThreadPoll比较适合执行大量的耗时较少的任务 -
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor继承自ThreadPoolExecutor。它的核心线程数量是固定的,而非核心线程数是没有限制的,并且当非核心线程闲置时会被立即回收.它主要用来在给定的延迟之后运行任务,或者定期执行任务。