Android中线程池的使用分析

作者: 程序员指北 | 来源:发表于2017-06-16 11:34 被阅读55次

引言:
说起线程池,学习过Java基础的同学估计都不陌生,Android中的线程池其实就是java的线程池。那么为什么线程池名声这么大,当然有其独特之处。这就引来了线程池到底有何优势。
线程池的优势:
Android中像访问内存卡,联网等耗时较长的任务时,需要在异步线程中进行,所以需要新开线程进行。但创建或者销毁线程伴随着系统的开销,频繁的创建和销毁线程,会较大的影响系统的性能。使用线程池,可用已有的闲置线程来执行新任务。
我们知道线程能共享系统资源,如果同时执行的线程过多,就有可能导致系统资源不足而产生阻塞的情况,运用线程池能有效的控制线程最大并发数,避免以上的问题。
线程池能够对线程进行有效的管理,比如延时执行,定时定周期循环执行等。

线程池ThreadPoolExecutor
既然线程池有这些优势,那么我们就要考虑怎样使用它。还是那句话,一个有追求的青年,要追根溯源。
android中的线程池来源于java中的线程池,那么我们就分析一下:
java中线程池的概念是一个接口,Excutor;其中ThreadPoolExecutor是这个接口的具体实现,也就是说线程池的所有定义及大部分操作将会从这个ThreadPoolExecutor中进行逻辑处理。那么我们就去看一下ThreadPoolExecutor的具体实现。
ThreadPoolExecutor的四个构造函数:

// 第一种构造器
public ThreadPoolExecutor(int corePoolSize, 
                        int maximumPoolSize, 
                        long keepAliveTime, 
                        TimeUnit unit,
                     BlockingQueue<Runnable> workQueue) {
    throw new RuntimeException("Stub!");
}

// 第二种构造器
public ThreadPoolExecutor(int corePoolSize, 
                        int maximumPoolSize, 
                        long keepAliveTime,
                     TimeUnit unit, 
                    BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
    throw new RuntimeException("Stub!");
}

// 第三种构造器
public ThreadPoolExecutor(int corePoolSize, 
                        int maximumPoolSize, 
                        long keepAliveTime, 
                        TimeUnit unit, 
                        BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
    throw new RuntimeException("Stub!");
}

// 第四种构造器
public ThreadPoolExecutor(int corePoolSize, 
                        int maximumPoolSize, 
                        long keepAliveTime, 
                        TimeUnit unit, 
                        BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
    throw new RuntimeException("Stub!");
}

看到这些构造函数的参数是不是一脸懵逼,不要急不要慌,其实搞明白第一种构造函数就可以了其他三个都是鸡肋。下面我们就详细的分析一下这些参数。

  1. corePoolSize:核心线程数 线程池新建线程的时候,如果当前线程总数小于corePoolSize,则新建的是核心线程,如果超过corePoolSize,则新建的是非核心线程;核心线程会一直保留,即使处于空闲状态,要想隔一段时间销毁它,必须指定ThreadPoolExecutor的allowCoreThreadTimeOut这个属性为true。

  2. maximumPoolSize:线程池中线程的最大数 最大数 = 核心线程数 + 非核心线程数;其中非核心线程就是在线程池中的核心线程已满,但线程总数小于最大数时创建的线程为费核心线程。

  3. keepAliveTime: 非核心线程保留时长 当非核心线程空闲时间超过保留时长时,就会被销毁掉。

  4. TimeUnit:keepAliveTime的单位,TimeUnit是一个枚举类型

public enum TimeUnit { 
          DAYS, 
          HOURS, 
          MICROSECONDS,
          MILLISECONDS, 
          MINUTES, 
          NANOSECONDS,
          SECONDS; }

5 BlockingQueue 线程池中的任务队列:维护着等待执行的Runnable对象;当所有的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,如果队列满了,则新建非核心线程执行任务。
其他的两个参数基本不用,需要详细了解的可以自行查看源码。

ThreadPoolExecutor的具体使用

认识完ThreadPoolExecutor,接下来就看一下怎样使用。其实很简单;

① new ThreadPoolExecutor对象,参数自行配置
② 使用对象调用execute方法,方法里传入runnable接口
③ 上②的runnable接口就是需要执行的任务

经过上面三步就完成了一个任务的添加执行。

常见的四种线程池对象

我们牛逼的Google攻城狮给我们封装了四种常用的线程池对象,就是对ThreadPoolExecutor进行不同参数进行详细配置的具体实现。当然我们也可以按照上述三步走进行自定义ThreadPoolExecutor线程池。但一般情况这四种线程池足够我们使用。

CachedThreadPool(): 直接从源码中寻找答案:

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

从上述源码可以看出可缓存线程池的特点:
① 线程数无限制
② 没有核心线程,都是非核心线程

使用方法:

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

2 . FixedThreadPool():定长线程池
源码:

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

特点:①:可控制线程最大并发数(线程数固定)
②:超出的线程会在队列中等待

使用方法:

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(int nThreads);

3 . ScheduledThreadPool():定时和周期性线程池

4 . SingleThreadExecutor():单一线程池
① 有且仅有一个工作线程执行任务
② 所有任务按照指定顺序执行,即遵循队列的入队出队规则

感谢
关于线程池的这篇文章参考(_liuzh)和(SEU_Calvin)的博客,感谢他们无私的分享。
———————————END BUT FINAL——————————-

相关文章

  • Java线程池总结

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • Java线程池详解

    本篇文章讲述Java中的线程池问题,同样适用于Android中的线程池使用。本篇文章参考:Java线程池分析,Ja...

  • Android线程池的使用

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

  • 线程池

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

  • 线程池创建和相关知识

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

  • 第十九周 线程池

    话题:线程池 Android 中的线程池有哪些?它们的区别是什么?为什么要使用线程池?关键字:线程池、Thread...

  • Android中的线程池

    为什么要使用线程池?Android 中的线程池有哪些?它们的区别是什么? 一、线程池的作用 重用线程池中的线程,可...

  • Android多线程规划

    Android上的线程池使用 Android线程 特性 Each thread costs a minimum o...

  • Android 中的线程池

    Android 中的四种线程池 在开发中使用线程池的优点 重用线程池中的线程,避免因为线程的创建和销毁带来的性能开...

  • 在android中使用ThreadPoolExector

    本篇文章主要介绍线程池,线程池executors及它们在android中的使用。我将使用一些例子代码来进行讲解。 ...

网友评论

    本文标题:Android中线程池的使用分析

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