「Android 进阶必学」线程池学习与使用

  1. 前言

线程池概念,以前跟着 Android 视频有学习过,但没有真正使用与梳理,间隔 时间较长后,忘记的差不多。需要养成良性习惯,学习了新的知识点后需要梳理,转换为自己理解语言使用技术文章描述,后续可以直接查阅笔记。
线程的创建与使用:

  1. 线程池

线程池可以理解为同时管理多个线程,通过 线程重用,减少创建与销毁对设备性能消耗,控制线程池中线程的并发数,避免线程争夺CPU资源造成阻塞,对线程进行管理,达到软件设计的需求;

  1. 线程池基础类「ThreadPoolExecutor 」

Execute 作为一个接口,具体实现类 ThreadPoolExecutor ;
Android中的线程池都是 直接或间接通过配置ThreadPoolExecutor 来实现不同特性的线程池

//核心线程数,除非allowCoreThreadTimeOut被设置为true,否则它闲着也不会死
int corePoolSize,
//最大线程数,活动线程数量超过它,后续任务就会排队
int maximumPoolSize,
//超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收
long keepAliveTime,
//枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等
TimeUnit unit,
//缓冲任务队列,线程池的execute方法会将Runnable对象存储起来
BlockingQueue workQueue,
//线程工厂接口,只有一个new Thread(Runnable r)方法,可为线程池创建新线程
ThreadFactory threadFactory)
ThreadPoolExecutor的各个参数所代表的特性注释中已经写的很清楚了,那么ThreadPoolExecutor执行任务时的心路历程是什么样的呢?(以下用currentSize表示线程池中当前线程数量)
(1) 当currentSize<corepoolsize时,直接启动一个核心线程并执行任务。 currentsize="" style=“font-size: inherit;color: inherit;line-height: inherit;”>=corePoolSize、且workQueue未满时,添加进来的任务会被安排到workQueue中等待执行。
(3) 当workQueue已满,但是currentSize<maximumpoolsize时,会立即开启一个非核心线程来执行任务。 currentsize="" style=“font-size: inherit;color: inherit;line-height: inherit;”>=corePoolSize、workQueue已满、并且currentSize>maximumPoolSize时,调用handler默认抛出RejectExecutionExpection异常。</maximumpoolsize时,会立即开启一个非核心线程来执行任务。></corepoolsize时,直接启动一个核心线程并执行任务。>

  1. Android 中常用的四类线程池

3.1 FixThreadPool「一堆人排队上公厕」

 * @param nThreads the number of threads in the pool
 * @return the newly created thread pool
 * @throws IllegalArgumentException if {@code nThreads <= 0}
 */
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

// 使用
Executors.newFixThreadPool(5).execute(Runnable);
(1)配置参数,FixThreadPool : 只有核心线程,数量固定,不会被回收,所有线程活动是,应为队列没有限制大小,新任务会等待执行;

3.2 CachedThreadPool「一堆人去一家很大的咖啡馆喝咖啡」

 * @param threadFactory the factory to use when creating new threads
 * @return the newly created thread pool
 * @throws NullPointerException if threadFactory is null
 */
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>(),
                                  threadFactory);
}

// 使用
Executors.newCachedThreadPool().execute(Runnable);
(1)CachedThreadPool只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创建新线程,否则利用空闲线程(60s空闲时间,过了就会被回收,所以线程池中有0个线程的可能)处理任务。

(2)任务队列SynchronousQueue相当于一个空集合,导致任何任务都会被立即执行。

(3)【前方高能,笔者脑洞】CachedThreadPool就像是一堆人去一个很大的咖啡馆喝咖啡,里面服务员也很多,随时去,随时都可以喝到咖啡。但是为了响应国家的“光盘行动”,一个人喝剩下的咖啡会被保留60秒,供新来的客人使用,哈哈哈哈哈,好恶心啊。如果你运气好,没有剩下的咖啡,你会得到一杯新咖啡。但是以前客人剩下的咖啡超过60秒,就变质了,会被服务员回收掉。

(4)比较适合执行大量的耗时较少的任务。喝咖啡人挺多的,喝的时间也不长。

3.3 SingleThreadPool「始终只有一个执行线程」

 * {@code newScheduledThreadPool(1)} the returned executor is
 * guaranteed not to be reconfigurable to use additional threads.
 * @return the newly created scheduled executor
 */
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService
        (new ScheduledThreadPoolExecutor(1));
}

//使用
Executors.newSingleThreadPool ().execute®;
3.4 ScheduledThreadPool「延迟执行和周期重复执行的线程池」

 * @param corePoolSize the number of threads to keep in the pool,
 * even if they are idle
 * @return a newly created scheduled thread pool
 * @throws IllegalArgumentException if {@code corePoolSize < 0}
 */
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

//使用,延迟1秒执行,每隔2秒执行一次Runnable r
Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILL

猜你喜欢

转载自blog.csdn.net/Coo123_/article/details/87882919
今日推荐