Android 线程池详解
来源:互联网 发布:python 改变路径 编辑:程序博客网 时间:2024/06/17 08:44
前言
做Android开发,有时会启动大量的线程,如果不适当的管理,会增加系统的开销,降低程序的性能。而线程池是Android性能优化的一个方案,有诸多好处:
1. 可以重用线程池里的线程,避免线程的创建和销带来的性能开销。 2. 可以控制线程池的最大并发数,避免大量线程之前抢占系统资源而造成阻塞现象。 3. 可以对线程进行管理,比如定时执行某线程或是循环执行等功能。
ThreadPoolExecutor
我们知道Java中有一个Executor这样一个接口。而ExecutorService就是继承了Executor的一个接口,真正实现的是ThreadPoolExecutor。先看下ThreadPoolExecutor的构造方法(比较常用的):
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); }
参数:
- corePoolSize:核心线程。
- maximumPoolSize:线程池所能容纳的最大线程数。
- keepAliveTime:非核心线程闲置的超时时长,如果超过这个值,非核心线程就会被回收。
- unit:用于指定keepAliveTime的时间单位。
- workQueue:线程池中的任务队列。
threadFactory:为线程池提供新建线程的功能。
这些参数配置在AsyncTask中就有所体现:
private static final String LOG_TAG = "AsyncTask"; private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; 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); /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
从AsyncTask的代码,我们可以看出:
- 核心线程=cpu核心数+1
- 核心线程没有超时机制,非核心线程的闲置超时时间为1秒
- 线程池的最大线程数为cpu核心数*2+1
任务队列的容量为128
ThreadPoolExecutor执行任务的时候,遵循以下规则:
1 如果线程池里的线程数量没有达到核心线程的数量,那么会直接启动一个核心线程来执行任务。
2 如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中的排队等待执行。
3 如果在步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这个时候如果线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来来执行。
4 如果步骤3中线程数量已经达到线程规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor 就会调用RejecteExecutionHandler的rejectedExcution方法来通知调用者。
Android中的线程池
Android中也通过配置ThreadPoolExecutor来实现了不同类型的线程池,下面我们来介绍最常用的4类线程池:
1.FixedThreadPool
通过调用Executes的newFixedThreadPool方法来创建:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
我们发现,FixedThreadPool线程池具备以下特性:
- 线程数量固定,在创建的时候,指定数量。
- 当线程处于空闲状态时,它们不会被回收,直到线程池被关闭。
- 当所有的线程都处于活动状态,新任务会处于等待状态,直到有线程空闲出来。
- 所有线程都是核心线程,且没有超时机制,队列也没有大小限制
2.CachedThreadPool
通过调用Executes的newCachedThreadPool方法来创建:
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
我们发现,CachedThreadPool线程池具备以下特性:
- 线程数量不固定,并且最大数为Integer.MAX_VALUE
- 当线程处于空闲状态时,如果闲置60秒就会被回收
- 当所有的线程都处于活动状态,新任务会创建新的线程执行,否则就使用闲置线程。
- 由此看来,CachedThreadPool线程池适合做大量的耗时较少的任务。
3.ScheduledThreadPool
通过调用Executes的newScheduledThreadPool方法来创建:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
我们发现,ScheduledThreadPool线程池具备以下特性:
- 核心线程是固定的,创建时指定
- 非核心线程是不固定的,闲置会被回收
- CachedThreadPool,主要用于执行定时任务和具有固定周期的重复任务
3.SingleThreadExecutor
通过调用Executes的newSingleThreadExecutor方法来创建:
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
我们发现,SingleThreadExecutor线程池具备以下特性:
- 内部只有一个核心线程
- 所有任务在线程中排队执行
- 感觉作用就是不用担心线程同步了,,
- Android 线程池详解
- Android 线程池详解
- Android线程池详解
- Android线程池详解
- Android线程池详解
- Android 线程池详解
- Android线程池详解
- Android(线程二) 线程池详解
- Android(线程二) 线程池详解
- Java(Android)线程池详解
- Android线程池ThreadPoolExecutor详解
- Android线程池使用详解
- 详解Android线程池ThreadPoolExecutor的教程
- android线程池详解(一)
- Android线程池ThreadPoolExecutor参数详解
- Android 线程池框架、Executor、ThreadPoolExecutor详解
- Android 线程池框架、Executor、ThreadPoolExecutor详解
- Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池
- 创建线程CreateThread的各个参数的名称
- 当我在后台底表直接修改了采购订单需求日期之后
- JPA联合查询方法二(应用托管的(application-managed)EntityManager对象 )
- BZOJ 3673 可持久化并查集 可持久化线段树
- 软件测试过程模型-前置测试模型
- Android 线程池详解
- 数据持久化
- 鼠标滚动事件mousewheel(DOMMouseScroll)
- iOS UITableView 和 UICollectionView 设置默认选中状态
- Redis+twemproxy(nutcracker)实现Redis多集群方案
- HttpClient的Post和Get方法
- Activity与Fragment通信方式
- Win7上Git安装及配置过程
- Git安装配置