Android 多线程之线程池
Android 多线程系列
Android线程池的真正实现是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:表示核心线程数。默认情况下核心线程会在线程池中一直存活,即使处于闲置状态。如果将ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那核心线程也会有超时策略,时间间隔由keepAliveTime指定
- maximumPoolSize:线程池的最大线程数。当活动的线程数达到这个数值后,后续的新任务就会被阻塞
- keepAliveTime:线程超时策略的超时时间,超过这个时间,非核心线程会被回收,核心线程要看allowCoreThreadTimeOut属性
- unit:keepAliveTime的单位
- workQueue:线程池的任务队列,如LinkedBlockingQueue,SynchronousQueue等
- ThreadFactory:线程工厂,为线程池创建新线程。ThreadFactory是一个接口,只有一个newThread方法
执行过程
- 如果线程池中的线程数未达到核心线程数,就创建核心线程执行新的任务
- 如果线程池中的线程数已经达到核心线程数,就将任务插入到任务队列中
- 如果无法将任务插入队列,说明队列已经满了,这个时候如果线程数未达到线程池的最大线程数,就创建非核心线程执行任务
- 如果任务队列满了,线程数已经达到最大值,就拒绝执行任务。ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法通知调用者
常见的四种线程池
FixedThreadPool
- 创建方法
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
- 可以看到默认构造函数需要传入核心线程数,且核心线程数和线程总数相同,也就是只有核心线程,同时没有超时时间,任务队列为LinkedBlockingQueue
- 由于只有核心线程,且没有超时策略,FixedThreadPool中的线程会一直存活,除非线程池被关闭。因此能快速响应外界的请求
- 所有的核心线程都处于活动状态时,新的任务都会处于等待状态
CachedThreadPool
- 创建方法
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
- CachedThreadPool只有非核心线程,且数量为Integer.MAX_VALUE,超时时间为60秒。
- CachedThreadPool采用的任务队列为SynchronousQueue,因此只要有新的任务来就会立刻被执行。
- 由于只有非核心线程,且有超时策略,当没有任务时,CachedThreadPool实际上一个线程也没有。
- CachedThreadPool比较适合执行大量耗时较少的任务
SingleThreadExecutor
- 创建方法
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
- SingleThreadExecutor只有一个核心线程,且没有超时策略,任务队列为LinkedBlockingQueue。
- SingleThreadExecutor确保所有的任务都在同一个线程中按顺序执行,这样这些任务就不需要处理线程同步的问题
ScheduledThreadPool
- 创建方法
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
- ScheduledThreadPool的核心线程数是固定的,必须在创建时指定。非核心线程数是没有限制的。当非核心线程空闲时会被立即回收。
- ScheduledThreadPool的任务队列为DelayedWorkQueue,因此可以用来执行一些定时任务和具有周期重复的任务
总结
- 以上的四种常用的线程池虽然是系统默认提供的,但是我们在使用时还是要仔细选择。
- 比如FixedThreadPool和SingleThreadExecutor中的任务队列为LinkedBlockingQueue,且没有指定队列的默认容量,而LinkedBlockingQueue的默认容量为Integer.MAX_VALUE,因此有可能造成队列任务过多而占用过多内存甚至发生OOM的情况
- ScheduledThreadPool和CachedThreadPool的问题则是线程最大的数量为Integer.MAX_VALUE,可能导致创建大量的线程,引发OOM
- 以上都是需要注意的地方。另外还是推荐用ThreadPoolExecutor根据实际需要手动创建线程池
欢迎关注我的微信公众号,期待与你一起学习,一起交流,一起成长!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
RecyclerView实现探探卡片滑动功能及优化
title: RecyclerView实现探探卡片滑动功能 date: 2018-10-07 10:35:56 tags: RecyclerView 代码实现 博客地址:https://blog.csdn.net/qq_39085422/article/details/78612132 我只掌握了RecyclerView基础用法,所以参考别人博客的代码实现。 我使用CardView代替RoundImageView实现圆角效果。 遇到的问题 1.CardView阴影显示不完全 Card_View_border.jpg 原因:将CardView作为最外层布局,可能是两个CardView重叠时,边界会融合到一起。 解决方法:在外层再套一层布局,比如LinearLayout之类的。 解决后效果图: Card_View.jpg 在文末会贴出我的布局代码。 2.左右滑,滑出时卡顿(未解决) 原因:adapter.notifyDataSetChanged(); 卡片滑出后需要删除对应的数据,对数据源进行remove()操作,之后通知adapter,这个时候会发生卡顿 3.向上下滑动时,动画衔接的不好...
- 下一篇
Android Handler机制(不含源码解析,适合新手理解)
一、官方解释 A Handler allows you to send and process [Message](https://developer.android.com/reference/android/os/Message.html) and Runnable objects associated with a thread's [MessageQueue](https://developer.android.com/reference/android/os/MessageQueue.html). Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver message...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果