AndroidAndroid开发经验谈程序员

了解android中的线程池

2017-09-29  本文已影响194人  四会歌神陈子豪
1.什么是线程池

我们想要使用一个线程的时候,可以创建一个线程,但如果要用多个线程,就要创建多个线程。但线程是一种受限制的系统资源,不可以无限制地产生,而且线程的创建和销毁都会产生相应的开销,如果频繁地创建和销毁线程,会影响系统的效率。这个时候我们就能够使用线程池。线程池会缓存一定量的线程,使得线程可以复用,线程执行完任务之后,并不会销毁,继续执行其他任务。通过线程池可以避免因为频繁创建和销毁线程造成的系统开销。

2.ThreadPoolExecutor

android中的线程池来源于java中的Executor接口,具体实现为 ThreadPoolExecutor类。先看看ThreadPoolExecutor的构造方法:

public class ThreadPoolExecutor extends AbstractExecutorService {
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);
 
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...
}

一共有7个参数,先来解析一下每个参数的含义。
int corePoolSize:线程池的核心线程数的最大值
线程池创建新线程的时候,如果当前线程数少于corePoolSize,则会创建核心线程,如果当前线程数大于corePoolSize,则会创建非核心线程。核心线程默认情况下会一直存活在线程池中,但如果将ThreadPoolExecutor 的 allowCoreThreadTimeOut 这个属性为 true,那么闲置的核心线程的存活时间就由keepAliveTime来决定,闲置时间超过keepAliveTime,该闲置的核心线程将会被终止。

int maximumPoolSize:该线程池中线程总数最大值
线程总数 = 核心线程数 + 非核心线程数

long keepAliveTime:非核心线程闲置时的超时时长

TimeUnit unit:keepAliveTime 的单位,是一个枚举
NANOSECONDS : 1微毫秒 = 1微秒 / 1000
MICROSECONDS : 1微秒 = 1毫秒 / 1000
MILLISECONDS : 1毫秒 = 1秒 /1000
SECONDS : 秒
MINUTES : 分
HOURS : 小时
DAYS : 天

BlockingQueue workQueue:该线程池的任务队列
BlockingQueue 又有多个类型

ThreadFactory threadFactory:线程工厂,为线程池提供创建新线程的功能。

RejectedExecutionHandler handler:当线程池无法执行新任务时,会抛出这个异常

3.线程池的分类

Android中最常见的四类线程池,都是通过配置ThreadPoolExecutor来实现的

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

CachedThreadPool是一种线程数量不定的线程池,只有非核心线程,最大线程数为Integer.MAX_VALUE,有空闲线程则复用空闲线程,若无空闲线程则新建线程,线程池中的空闲线程超时时长为60秒,一定程序减少频繁创建/销毁线程,减少系统开销。
试用方法:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            SystemClock.sleep(1000);
        }
    };
    ExecutorService cacheThreadPool = Executors.newCachedThreadPool();
    cacheThreadPool.execute(runnable);
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}

FixedThreadPool是一种线程数量固定的线程池,只有核心线程并且这些核心线程不会倍回收,可控制线程最大并发数,超出的线程会在队列中等待。
试用方法:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            SystemClock.sleep(1000);
        }
    };
    ExecutorService fixedThreadPool= Executors.newFixedThreadPool(4);
    fixedThreadPool.execute(runnable);
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}

ScheduledThreadPool的核心线程是固定的,非核心线程是没有限制的,并且非核心线程闲置时会马上被回收。主要支持定时及周期性任务执行。
试用方法:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            SystemClock.sleep(1000);
        }
    };
   ExecutorService scheduledThreadPool =Executors.newScheduledThreadPool(4);
    scheduledThreadPool .execute(runnable);
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
                (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
}

SingleThreadExecutor只有一个核心线程,所有任务按照指定顺序执行,即遵循队列的入队出队规则。
试用方法:

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            SystemClock.sleep(1000);
        }
    };
    ExecutorService singleThreadPool =Executors.newSingleThreadPool();
    singleThreadPool .execute(runnable);
参考:

http://blog.csdn.net/lift_class/article/details/70216690


更多精彩文章请扫描下方二维码关注微信公众号"AndroidCzh":这里将长期为您分享原创文章、Android开发经验等!
QQ交流群: 705929135

上一篇 下一篇

猜你喜欢

热点阅读