美文网首页
Android常用的线程池

Android常用的线程池

作者: 超级绿茶 | 来源:发表于2020-02-14 16:03 被阅读0次

Android应用开发是一种多线程编程,Android中的线程概念源于Java,所以线程的用法也直接用的是Java的。最简单的方法是直接new Thread一个线程出来操作,但从性能优化的角度来说并不推荐这种操作,建议使用线程池以减少线程的创建和销毁时的系统开销。而这一理念在Android的各种框架中也得到体现,如果看源码的话会发现框架内部涉及到线程的地方基本都会用到线程池。

说到线程池肯定要说一下ThreadPoolExecutor类,这个类在创建时可以通过不同的参数配置出不同需求的线程池。构造器定义如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory)
  • corePoolSize:定义核心线程池的大小。就是能容纳多少个线程,这些线程在执行完任务后不会被销毁,以便反复使用。
  • maximumPoolSize:定义线程池的最大容量。当核心线程池满了后还能扩充出多少新的线程出来。
  • keepAliveTime:非核心线程的空闲时长,超过这个时长就销毁。
  • TimeUnit:keepAliveTime的时间单位。
  • workQueue:线程队列,核心线程满了以后新提交的任务会在这个队列里排队,线程队列又分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种。
  • threadFactory:线程的创建工厂,主要是定义线程的创建方法,这个参数需要传入一个实现了ThreadFactory接口的对象。

当线程池创建成功后可以通过execute方法把线程对象提交给线程池。ThreadPoolExecutor会创建新的线程并执行线程任务,每次提交都会创建,直到创建的线程数量大于核心线程数时就需要用到线程队列了。ThreadPoolExecutor又根据四种类型的队列有四种不同的线程处理方式。

1.直接提交队列-通过SynchronousQueue实现。这个队列说白了就是一个长度为0的队列,任务放入队列后就立马会新建一个线程并处理,直到线程总数等于maximumPoolSize。

2.有界队列-通过ArrayBlockingQueue实现。ArrayBlockingQueue对象在创建时需要指定队列的容量上限,然后提交的线程任务会被存入这个队列,当队列存满时会创建新的线程并执行队列中的任务,直到线程总数等于maximumPoolSize为止。

3.无界队列-通过LinkedBlockingQueue实现。这种队列的容量是无限(只受内存容量影响)的,也就是说这个队列永远不会满,所以就不会创建新线程而只会等核心线程空闲后执行队列任务。使用这种队列要确保核心线程总能及时处理完任务后再来处理队列中的任务。

4.优先任务队列-通过PriorityBlockingQueue实现。可以视为按线程优先级运行的无界队列。

ThreadPoolExecutor的构造器还可以传入一个类型为RejectedExecutionHandler的参数,这个参数称为“拒绝策略”。会在线程队列存满并且创建的线程总数大于maximumPoolSize时触发,用于在这种情况下还有新提交的任务要怎么处理。主要有四种策略:

  1. AbortPolicy策略:直接抛异常,不指定时默认使用这个策略。
  2. CallerRunsPolicy策略:将线程任务放到当前线程执行。
  3. DiscardOledestPolicy策略:丢充最先加入的线程任务。
  4. DiscardPolicy策略:丢失提交的线程任务。

此外,Java也根据ThreadPoolExecutor的配置预置了四种不同功能的线程池:FixedThreadPool、CachedThreadPool、SingleThreadExecutor和ScheduledThreadPool。这四种线程池都可以通过Executors的相应静态方法创建。

FixedThreadPool

这种线程池的特点就是线程总数是固定不变的。当提交的线程任务大于线程总数时存入队列中排队处理。通过newFixedThreadPool静态方法创建。

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>(),
                                      threadFactory);
}

CachedThreadPool:

这种线程池的特点是可创建的线程总数不限,且线程池内的线程在空闲时都能被销毁掉以便节省资源。通过newCachedThreadPool的静态方法创建。

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}

通过源码可以看出核心线程总数为0,而最大线程数是Int类型的最大值,因为没有了核心线程数,所以创建出来的线程都是非核心的,在60秒闲置期过后就能被销毁掉。

SingleThreadExecutor

这个线程池的特点是只有一个线程,所以提交的线程任务都是排队执行,不存在并发执行的情况。可以通过newSingleThreadExecutor方法创建。

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

ScheduledThreadPool

是一种特殊的线程池,能够定时和周期性的执行线程任务,当池中的线程数量小于核心线程数时直接创建线程,但不执行,需要通过scheduleAtFixedRate或scheduleWithFixedDelay方法设置执行的周期。如果线程数量大于核心线程数时就把线程任务存到线程队列,等于有空间的核心线程时再执行。通过newScheduledThreadPool静态方法。

public static ScheduledExecutorService newScheduledThreadPool(
            int corePoolSize, ThreadFactory threadFactory) {
        return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
// ScheduledThreadPoolExecutor继承自ThreadPoolExecutor
public ScheduledThreadPoolExecutor(int corePoolSize,
                                       ThreadFactory threadFactory) {
        super(corePoolSize, Integer.MAX_VALUE,
              DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
              new DelayedWorkQueue(), threadFactory);
}

传送门:Android常用的线程池

点击链接加入QQ群聊:https://jq.qq.com/?_wv=1027&k=5z4fzdT
或关注微信公众号:口袋里的安卓

相关文章

  • 线程池创建和相关知识

    线程池创建(单例):Android线程池得要这么用 - 简书 线程池相关知识:Android开发之线程池使用总结 ...

  • java线程池技术总结

    常用的线程池有哪些? 常用线程池的优缺点对比?

  • Android常用的线程池

    Android应用开发是一种多线程编程,Android中的线程概念源于Java,所以线程的用法也直接用的是Java...

  • Android中线程池的使用

    线程池算是Android开发中非常常用的一个东西了,只要涉及到线程的地方,大多数情况下都会涉及到线程池。Andro...

  • Executors

    Executors生成常用的几种线程池执行者 可缓存线程池 定长的线程池 定时线程池 ScheduledThrea...

  • Android线程池的使用

    一、线程与线程池,为什么要使用线程池 1、Android中的线程 在Android中有主线程和子线程的区分。主线程...

  • 线程池

    话题:线程池Android中的线程池有哪些?它们的区别是什么?为什么要使用线程池? 线程是Android里面一个很...

  • java并发编程-线程池

    参考 常用线程池: newSingleThreadExecutor创建一个单线程的线程池。这个线程池只有一个线程在...

  • 线程池相关

    线程池 1.几种常用的线程池 包括:newSingleThreadExecutor、newFixedThreadP...

  • 异步任务-- AsyncTask

    一、为什么要异步任务?Android单线程模型耗时操作放在非主线程中 二、异步加载最常用的两种方式多线程/线程池A...

网友评论

      本文标题:Android常用的线程池

      本文链接:https://www.haomeiwen.com/subject/skpdfhtx.html