Android中的线程池理解

Android中的线程池

一、线程池的作用:

(1)避免线程重复创建和销毁造成性能浪费
(2)控制线程最大并发数,避免大量线程之间相互抢占资源造成阻塞
(3)便于对线程进行简单的管理

二、ThreadPoolExecutor

Android的线程池来源于java的Executor(接口),其具体实现为ThreadPoolExecutor。
接下来为ThreadPoolExecutor,其构造方法为:

     public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                   TimeUnit unit,
                                   BlockingQueue<Runnable> workQueue,
                                   ThreadFactory threadFactory)

接下来介绍这上面各个参数的具体含义:
corePoolSize:核心线程数,啥为核心线程数?一般情况下,核心线程在线程池中都是一直存活的,即使它们处于闲置状态,除非设置ThreadPoolExecutor的allowCoreThreadTime这个属性为true,那么当闲置时间超过keepAliveTime时,核心线程就会停止。

maximunPoolSize:这个是线程池中的最大线程数,当活动线程达到这个数目时,到来的任务就会被阻塞

keepAliveTime:非核心线程闲置的超时时长,超过这个时间,非核心线程就会被回收。

unit:keepAliveTime的时间单位。

workQueue:任务队列,通过线程池的execute提交的Runnable对象会存储到这个参数中。

threadFactory(接口):为线程池提供创建新线程的功能,里面唯一的方法:Thread newThread(Runnable r)。

接下来参考下AsyncTask中对ThreadPoolExecutor的配置:

 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
 private static final int KEEP_ALIVE = 1;
 private static final ThreadFactory sThreadFactory = new ThreadFactory() {
 private final AtomicInteger mCount = new AtomicInteger(1);
 public Thread newThread(Runnable r) {
 	return new Thread(r,"AsyncTask #" + mCount.getAndIncrement());
 }
 };
 private static final BlockingQueue<Runnable> sPoolWorkQueue =
 							new LinkedBlockingQueue<Runnable>(128);

 public static final Executor THREAD_POOL_EXECUTOR
 = new ThreadPoolExecutor(CORE_POOL_SIZE,MAXIMUM_POOL_SIZE,KEEP_ALIVE,sThreadFactory

从上代码可知:
(1)核心线程数为CPU核心数减1,再和4比较取值;
原因:防止后台任务将CPU资源完全耗尽,减掉这个1是留给主线程使用的。正常来说核心线程数应设置为CPU核心数+1,其原因是:提高CPU的利用率。
我们需要根据任务是计算密集型(指处理这种任务时,线程不会发生阻塞,线程不阻塞就一定程度代表 CPU 一直在忙碌)或者是IO密集型(指运行该类任务时线程多会发生阻塞,一旦阻塞,CPU 就多被闲置)来设置线程池的大小。
对于计算密集型的任务,在有N 个处理器的系统上,当线程池的大小为 N+1 时,能实现 CPU 的最优利用率。
(2)线程池最大的线程数为CPU核心数的2N+1;(IO密集型)
(3)核心线程无超时机制,非核心线程在闲置时的超时时间为1秒;
(4)任务队列的容量为128;

三、线程池的分类

主要有四类:FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor
(1)FixedThreadPool,通过Executors的newFixedThreadPool方法来创建

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

特点·里面只有核心线程,线程数量固定。线程处于空闲状态时,并不会被回收。所有线程都处于活动状态的时候,新任务都会处于等待状态。

(2)CachedThreadPool,通过Executors的newCachedThreadPool方法来创建。

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

特点:里面只有非核心线程,其最大线程数可以任意大。超时机制为60S,超过这个数,线程池中的线程都会被超时停止,这个时候CachedThreadPool为空。适合执行大量耗时比较少的任务。

(3)ScheduledThreadPool,通过Executors的newScheduledThreadPool方法来创建。

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

特点:核心线程数固定,非核心线程无限制,非核心线程一闲置马上会被回收。

(4)SingleThreadExecutor,通过Executors的newSingleThreadExecutor方法来创建。

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

特点:所有任务都在同一个线程中按顺序执行。

参考自《Android开发艺术探索》

发布了14 篇原创文章 · 获赞 45 · 访问量 2451

猜你喜欢

转载自blog.csdn.net/weixin_42683077/article/details/99930212