浅谈android的线程池
2015-11-27 21:35
531 查看
其实在我眼里,线程池是一个很高端的东西,它会管理很多线程,并在进程中进行多线程的操作,是一个很高效且方便使用的东西。本篇文章就说说我对线程池的认识。
ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnalbe>workQueue,ThreadFactory threadFactory)
corePoolSize:核心线程数量,它会一直存在,没任务就处理闲置状态 。如果allowCoreThreadTimeOut设置为true,则闲置的核心线程会有超时策略,时间由keepAliveTime控制,当超时时,核心线程就会被终止。
maximumPoolSize:线程池能容纳的最大线程数,当活动数达到这个数时,后续的新任务将会被阻塞。
keepAliveTime:超时时非核心线程会被回收,如果allowCoreThreadTimeOut设置为true,核心线程也会被回收。
unit:指定keepAliveTime的单位。TimeUnit.MILLISECONDS(毫秒),TimeUnit.SECONDS(秒)等。
workQueue:线程中的任务队列,通过线程池的excute方法提交的Runnable会存储到这参数中。
threadFactory:线程工厂,为线程池提供创建新线程的功能。
了解了上面的概念后,我们来看下android线程池的分类。
二,线程池的分类
1.FixedThreadPool
这是一种线程数量固定的线程池。处理空闲状态时,并不会被回收,除非线程池关闭。它的源码如下:
2.CacheThreadPool
是一种线程数量不定的线程池,只有非核心线程,并且最大线程数可以说是无穷大。当线程池中的线程都处于活动状态时,创建新线程。这类线程适合执行大量耗时较少的任务。看下它的构造方法:
同样很好理解,没有核心线程,最大线程娄是MAX_VALUE,基本可以理解成无上限,超时机制是60秒,由上分析可知,它在闲置60秒后会被回收,所以基本不占系统资源。看下它的用法。
3.scheduledThreadPool
核心线程数量是固定的,而非核心线程数是没有限制的,并且非核心线程闲置时会被立即回收,可用于执行定时和具有固定周期的重复任务。看下它的构造方法:
4.SingleThreadExecutor
内部只有一个线程,确保任务都在一个线程中按顺序执行。这个多用于串行处理情况。不用考虑并发的问题。它的构造方法如下:
一,线程池的基本概念
线程池有很多优点,比如避免了重复创建和销毁线程而降低了程序的运行效率,其次它可以很方便的控制线程的最大并发数,在一定程度上可以减少线程间的阻塞等。在android中线程池是由java的Executor实现的。它的真正实现类是ThreadPoolExecutor,下面是它的构造方法和相关介绍。ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnalbe>workQueue,ThreadFactory threadFactory)
corePoolSize:核心线程数量,它会一直存在,没任务就处理闲置状态 。如果allowCoreThreadTimeOut设置为true,则闲置的核心线程会有超时策略,时间由keepAliveTime控制,当超时时,核心线程就会被终止。
maximumPoolSize:线程池能容纳的最大线程数,当活动数达到这个数时,后续的新任务将会被阻塞。
keepAliveTime:超时时非核心线程会被回收,如果allowCoreThreadTimeOut设置为true,核心线程也会被回收。
unit:指定keepAliveTime的单位。TimeUnit.MILLISECONDS(毫秒),TimeUnit.SECONDS(秒)等。
workQueue:线程中的任务队列,通过线程池的excute方法提交的Runnable会存储到这参数中。
threadFactory:线程工厂,为线程池提供创建新线程的功能。
了解了上面的概念后,我们来看下android线程池的分类。
二,线程池的分类
1.FixedThreadPool
这是一种线程数量固定的线程池。处理空闲状态时,并不会被回收,除非线程池关闭。它的源码如下:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }由上面介绍的ThreadPoolExecutor可知,FixedThreadPool的核心线程有nThreads条,最大线程也相同,这证明了它没有非核心线程,且FixedThreadPool没有超时策略,所以空闲时线程不会被回收。此外它的任务队列也是无限大的。它适合用于需要快速响应的外界请求的情况下。接下来看下它的用法。
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); fixedThreadPool.execute(Runnable);用法很简单,只需要使用Executors就可创建FixedThreadPool,并初始化线程数。看到这个,以后开线程就不需要再用Thread了。
2.CacheThreadPool
是一种线程数量不定的线程池,只有非核心线程,并且最大线程数可以说是无穷大。当线程池中的线程都处于活动状态时,创建新线程。这类线程适合执行大量耗时较少的任务。看下它的构造方法:
<pre name="code" class="java"><pre name="code" class="java"> public static final int MAX_VALUE = 0x7FFFFFFF;public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
同样很好理解,没有核心线程,最大线程娄是MAX_VALUE,基本可以理解成无上限,超时机制是60秒,由上分析可知,它在闲置60秒后会被回收,所以基本不占系统资源。看下它的用法。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(runnable);
3.scheduledThreadPool
核心线程数量是固定的,而非核心线程数是没有限制的,并且非核心线程闲置时会被立即回收,可用于执行定时和具有固定周期的重复任务。看下它的构造方法:
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }super就相当于调用了ThreadPoolExecutor,看下它的用法:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4); // 1s后执行command scheduledThreadPool.schedule(runnable, 1000, TimeUnit.MILLISECONDS); // 延迟10ms后,每隔1000ms执行一次command scheduledThreadPool.scheduleAtFixedRate(runnable, 10, 1000, TimeUnit.MILLISECONDS);
4.SingleThreadExecutor
内部只有一个线程,确保任务都在一个线程中按顺序执行。这个多用于串行处理情况。不用考虑并发的问题。它的构造方法如下:
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }没什么好解释的,来看下它的用法:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(runnable);</span>分析完所有线程池后,我们得知,不同线程池有不同的应用环境,并没有说哪个比较好。在实际情况中我们要根据自己的需求来适当的选择。其实线程池在android的源码中有大量的使用,下一篇博客将讲解下AsyncTask的源码解析,里面就运用了线程池。
相关文章推荐
- Android开发之RadioGroup与RadioButton控件使用
- 请把Camera hold住 - Android高通平台调试Camera驱动全纪录
- android 各种小项目
- 【Android笔记】DatePicker,TimePicker
- 安卓开发中Handler的应用
- 使用 Intel HAXM 为 Android 模拟器加速,媲美真机
- split 的 使用方法
- 分析Android的进程通信机制
- Android中的消息通知Toast和Notification
- 源码解析EventBus
- 浅谈屏幕适配之measure(上)
- Android开发者的Kotlin:书
- mac下反编译Android的apk步骤
- android分页代码
- Android开发之Spinner控件使用
- Android编程之BitmapFactory.decodeResource加载图片缩小的原因及解决方法
- 王学岗帧动画(一)——帧动画的简单实用
- 源码级分析Android系统启动流程
- 【Android笔记】ListView
- mac电脑批量解压android apk文件图形化工具--apkDecode