android线程池简书,Android中的线程池

为什么要有线程池

说道为什么要有线程池,就不得说下线程池能给我们带来什么好处,都有什么优点呢?

优点

线程池可以重复利用池中的线程,可以有效的避免创建线程和销毁线程所带来的性能损耗。我们知道正常的多线程都是执行完一个任务就会将当前的线程销毁,然后触发GC的垃圾回收,这样频繁的GC操作,会导致应用程序卡顿。

能有效控制线程池的最大并发数,这样可以避免大量的线程去争夺系统的资源,这样可以避免争夺资源而产生的系统卡顿和阻塞的现象。

能够对线程进行简单的管理操作,意思就是我们可以自定义线程池来满足我们得需要。

Android中的线程池介绍

Android中的线程池是源自于Java中的Executor,然而Executor是一个接口,它的唯一实现类是ThreadPoolExecutor也就是线程池类,接下来我们就看看这个ThreadPoolExecutor为我们提供了怎样的线程操作。

ThreadPoolExecutor

ThreadPoolExecutor是提供了一系列的配置参数来配置线程池,而我们Android中的线程池都是通过自定义ThreadPoolExecutor的参数来达到想要的功能。

ThreadPoolEcecutor的配置参数介绍

ThreadPoolExecutor是线程池的真正实现,它的构造方法提供了一系列参数来配置线程池,接下来我们就来看看这些构造方法中的配置参数。

public ThreadPoolExecutor(int corePoolSize,

int maximumPoolSize,

long keepAliveTime,

TimeUnit unit,

BlockingQueue workQueue,

ThreadFactory threadFactory,

RejectedExecutionHandler handler) {

this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

Executors.defaultThreadFactory(), handler);

}

corePoolSize :核心线程数

线程池中的核心线程数,默认情况下,核心线程会在线程池中一直存活,即使它们处于空闲的状态下。有一个特例就是线程池中有一个配置参数 allowCoreThreadTimeOut设置为true,那么核心线程池就得去遵守超时策略,在新任务到来之前核心线程池存活时间受keepAliveTime决定。空闲的线程超过这个时间就会被销毁。

maximumPoolSize: 最大线程数

线程池中所能容纳的最大线程数,当线程池中所能容纳的数达到饱和的状态,后续的任务就会被阻塞。

keepAliveTime

针对非核心线程来说,当处于空闲的状态时候,如果超过这个时间,非核心线程就会被回收。针对核心线程来说,当参数allowCoreThreadTimeOut设置为true,keepAliveTime同样适用于空闲的核心线程。

unit:时间单位

是用于指定keeoAliveTime的单位。

workQueue:任务队列

线程池通过execute方法提交的Runnable对象都会存储在这个任务队列中。

threadFactory :线程工厂

线程池通过线程工厂来创建新的线程,ThreadFactory是一个接口,只有一个newThread(Rnnnable r)方法。

RejectedExecutionHandler:饱和策略

当线程池的数量和任务队列的数量都满的情况,所应对的策略,默认是AbordPolicy,表示无法处理新的任务,并抛出RejectedExecutionException异常。

ThreadPoolExecutor 执行任务遵守的规则

如果线程池中的线程数量没有超过核心线程数量,那么接下来的要执行的任务,会直接启动一个核心线程中执行该任务。

如果线程池中的线程数量超过核心线程数,那么接来的任务会被插入到任务队列中排队等待。

如果当线程中的数量超过核心线程数,并且无法将任务插入到任务队列中,这往往是由于任务队列已经满了,这个时候如果线程数没有达到最大线程数,最自动启动一个非核心线程去执行该任务。

如果任务队列已满 并且线程数应达到最大的线程数。那么就拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectExcution方法来通知调用者。

下面用一张图总结一下上面遵守的执行规则

5885f4ef316b

线程池执行的原理图.png

Android中线程池的分类

接下来介绍的几种线程池都是通过ThreadPoolExecutor配置参数演化而来的,来实现特定的功能。

FixedThreadPool(定长线程池)

构造方法分析

public static ExecutorService newFixedThreadPool(int nThreads) {

return new ThreadPoolExecutor(nThreads, nThreads,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue());

}

FixedThreadPool 是通过newFixedThreadPool方法创建的,内部看源码得知 方法内部通过new创建了一个FixedThreadPool,其中传入了参数,通过参数分析得知,这个线程池中有固定的线程数,并且只有核心线程存在,并且核心线程不会被回收,当所有的线程都是处于工作的时候,新的任务会存入在任务队列中,直到有核心线程空余的时候,会去执行任务队列中的任务。

CachedThreadPool(可缓存线程池)

构造方法的分析

public static ExecutorService newCachedThreadPool() {

return new ThreadPoolExecutor(0, Integer.MAX_VALUE,

60L, TimeUnit.SECONDS,

new SynchronousQueue());

}

CachedThreadPool 是通过 newCachedThreadPool方法得到的,看构造方法入参分析得知,这个线程池中没有核心线程池,线程池中最大线程数为Integer.MAX_VALUE意味的可以容纳无限数量的非核心线程,非核心线程的超时策略为60s,当空闲的非核心线程超过60s就会被回收。SynchronousQueue其实是一个空队列进入的任务会被立马执行,不是处于空闲的线程或者就是创建新的线程去执行,CachedThreadPool适合用于大量的耗时少的任务上。

这里特殊说明下CachedThreadPool执行原理,首先执行execute()方法,此时SynChronousQueue队列会执行offer方法,来提交任务,然后同时查看线程池中是否有空闲线程在执行SynChronousQueue的poll方法来移除任务,如果有就相当于配对成功了,如果没有就创建新的非核心线程去队列中取任务,然后执行此任务。

ScheduledThreadPool(定时线程池)

构造方法分析

public static ScheduledExecutorService newScheduledThreadPool(

int corePoolSize, ThreadFactory threadFactory) {

return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);

}

public ScheduledThreadPoolExecutor(int corePoolSize,

ThreadFactory threadFactory) {

super(corePoolSize, Integer.MAX_VALUE,

DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,

new DelayedWorkQueue(), threadFactory);

}

ScheduledThreadPool是通过newScheduledThreadPool方法来得到的,我们通过入参的参数分析得知,这是一个固定的核心线程的线程池,非核心线程是无限大的,当非核心线程空闲超过10毫秒(事件极短,相当于立即回收)回进行回收。该线程池适合用于指定定时任务和具有周期的重复任务。

SingleThreadExecutor(单线程线程池)

构造方法分析

public static ExecutorService newSingleThreadExecutor() {

return new FinalizableDelegatedExecutorService

(new ThreadPoolExecutor(1, 1,

0L, TimeUnit.MILLISECONDS,

new LinkedBlockingQueue()));

}

SingleThreadExecutor是通过方法newSingleThreadExecutor方法得到的,通过分析构造方法的参数得知,只有一个核心线程,最大线程数为1,不会创建非核心线程,这样能顺序执行任务队列中的任务,这个线程能控制并发数,避免了大量线程争夺资源而产生的问题。

总结

下面我们从各方面总结和对比下Android中的线程池

5885f4ef316b

Android中的线程池.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值