Android线程优化之线程池的详解
本文授权发布公众号【刘桂林】,星球【Hi Android】
ThreadPoolExecutor还是有很多可讲的,但是我选择的还是着重讲解Android中的四个线程池,网上对ThreadPoolExecutor的例子太多了,也比较杂,大家可以去看看。
Android中的线程池的概念来源于Java中的Executor,Executor是一个接口,真正的线程池的实现为ThreadPoolExecutor,其中所实现的四个线程池每一个的作用都是不一样的,我们一起来看下:
FixThreadPool
FixThreadPool通过如下代码实现:
ExecutorService service = Executors.newFixedThreadPool(5);
Runnable r = new Runnable() {@Overridepublic void run() {Log.i(TAG, "newFixedThreadPool");}
};
service.execute(r);
队列线程池,因为核心线程池是固定的,所以不管你如何execute,都会一个个来执行完成,因为直接创建使用,没有回收,所以他的优势是响应速度很快,效率更高。
这里我们可以模拟一下:
ExecutorService service = Executors.newFixedThreadPool(2);for (int i = 0; i < 10; i++) {final int finalI = i;service.execute(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);Log.i(TAG, "newFixedThreadPool:" + finalI );} catch (InterruptedException e) {e.printStackTrace();}}});
}
这里指定核心线程数为2,然后执行10个任务,得到的结果:
可以看出,首先他是无序的,其次他每隔两秒钟打印两个,也就验证了刚才的说法,他线程数满了之后需要等待,就是排队打饭一样。
SingleThreadPool
顾名思义,这个都不需要指定核心线程数,代码如下:
ExecutorService service = Executors.newSingleThreadExecutor();
Runnable r = new Runnable() {@Overridepublic void run() {Log.i(TAG, "newSingleThreadExecutor");}
};
service.execute(r);
这个其实和newFixedThreadPool(1)是一样的,SingleThreadPool主要还是为了线程同步而来的,newFixedThreadPool可以同时执行多任务,所以肯定不是同步的,如果什么场景需要线程同步,那SingleThreadPool再合适不过了。
如果我们把上面的例子改成SingleThreadPool:
ExecutorService service = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int finalI = i;service.execute(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);Log.i(TAG, "newSingleThreadExecutor:" + finalI );} catch (InterruptedException e) {e.printStackTrace();}}});
}
可以得到的结论:首先他是有序的,其次他每隔两秒则打印一次,而Log的输出也刚好验证了我的结论:
CachedThreadPool
CachedThreadPool还是比较多使用的,他不需要指定线程数,因为他的线程数很大,但是不存在核心线程,这也就意味着经常被回收,他的回收思路是,执行任务,任务结束后,保留60s,在60s来了新任务则继续使用刚才的线程,如果60s内无任务则回收线程,有点类似吃饭,你去盛饭没关系,但是你吃完走了我就要收盘子,间隙就在60s
ExecutorService service = Executors.newCachedThreadPool();
Runnable r = new Runnable() {@Overridepublic void run() {Log.i(TAG, "newCachedThreadPool");}
};
service.execute(r);
我们继续改造我们的示例代码:
ExecutorService service = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {final int finalI = i;service.execute(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);Log.i(TAG, "newCachedThreadPool:" + finalI );} catch (InterruptedException e) {e.printStackTrace();}}});
}
这段代码在前面两个线程池都使用到了,就是用来告诉你他们的区别,我们使用newCachedThreadPool执行后得到的结果:
看Log,我们得到的结论是:首先他也是无序的,并且他因为子线程够多,所以sleep两秒后直接全部打印出来了。
ScheduledThreadPool
这是一个可操作性较强的线程池,也是唯一一个可循环的线程池,便于一些重复性的工作使用
ScheduledExecutorService service = Executors. newScheduledThreadPool (5);
Runnable r = new Runnable() {@Overridepublic void run() {Log.i(TAG, "newScheduledThreadPool");}
};
Log.i(TAG,"start");
service.scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);
scheduleAtFixedRate中有四个参数,第一个是任务,第二个是延时时长,第三个是循环时长,第四个是单位,也就是说,当启动scheduleAtFixedRate之后,在1s后才开始执行这个间隔2s的任务不断循环,可以这样理解,启动任务后,这里延时1s,然后才开始执行任务,以后每隔2s重复执行
我们拿着示例继续改造:
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);for (int i = 0; i < 10; i++) {final int finalI = i;service.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);Log.i(TAG, "newCachedThreadPool:" + finalI );} catch (InterruptedException e) {e.printStackTrace();}}},1000,2000,TimeUnit.MILLISECONDS);
}
这段代码比上面的复杂一些,我们看打印:
这里得到的是什么结论呢?比较多,首先,他是无序的,其次他间隔2s无限重复,并且启动这个县城需要3s,也就是延迟的1s + sleep的3s。
到这里我相信大家还是比较清晰的认知线程池,但是线程池是结合实战的,不然的话也都是纸上谈兵,但是一般线程池也只是替换new Thread的操作,所以示例的话,大家可以自行寻找一下,后续的实战项目文章,我再带领大家学习线程池。
有兴趣可以加入我的星球:Hi Android , 里面可都是我手撸的新鲜文章,高质量你值得拥有!
进入星球你可以做什么?
1.我的所有视频可以观看
2.发布提问贴可以得到满意的答案
3.可指定我写你感兴趣的技术文章
4.初学者可配套视频辅导
5.有机会线下交流聚会
Android线程优化之线程池的详解相关推荐
- Android性能优化之APK瘦身详解(瘦身73%)
image 公司项目在不断的改版迭代中,代码在不断的累加,终于apk包不负重负了,已经到了八十多M了.可能要换种方式表达,到目前为止没有正真的往外推过,一直在内部执行7天讨论需求,5天代码实现的阶段. ...
- Android 性能优化之线程优化
Android线程调度机制 线程调度模型 分时调度模型: 所有的线程轮流获得CPU使用权,平均分配每个线程占用的cpu时间 抢占式调度模型(Android):优先让可运行池中的优先级高的线程占用cpu ...
- async spring 默认线程池_Spring boot注解@Async线程池实例详解
这篇文章主要介绍了Spring boot注解@Async线程池实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 从Spring3开始提供了@A ...
- python线程池原理_Python定时器线程池原理详解
这篇文章主要介绍了Python定时器线程池原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 定时器执行循环任务: 知识储备 Timer(int ...
- 线程池源代码详解,参数详解
线程池源代码详解,参数详解 ThreadPoolExecutor 构造函数源代码 public ThreadPoolExecutor(int corePoolSize, int maximumPool ...
- Java线程池ThreadPool详解
Java线程池ThreadPool详解 1. 线程池概述 1.1 线程池简介 1.2 线程池特点 1.3 线程池解决问题 2. 线程池原理分析 2.1 线程池总体设计 2.6 线程池流转状态 2.2 ...
- Android 性能优化(62)---存检测、卡顿优化、耗电优化、APK瘦身——详解篇
Android 性能优化,内存检测.卡顿优化.耗电优化.APK瘦身--详解篇 自2008年智能时代开始,Android操作系统一路高歌,10年智能机发展之路,如今 Android 9.0 代号P 都 ...
- Android 各大厂面试题汇总与详解(持续更新)
介绍 目前网络中出现了好多各种面试题的汇总,有真实的也有虚假的,所以今年我将会汇总各大公司面试比较常见的问题,逐一进行解答.会一直集成,也会收集大家提供的面试题,如有错误,请大家指出,经过排查存在,会 ...
- android组件用法说明,Android第三方控件PhotoView使用方法详解
Android第三方控件PhotoView使用方法详解 发布时间:2020-10-21 15:06:09 来源:脚本之家 阅读:74 作者:zhaihaohao1 PhotoView的简介: 这是一个 ...
- Android JNI使用方法,JNI机制详解
Android JNI使用方法,JNI机制详解 JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此N ...
最新文章
- postgres循环sql
- Linux文件查找之findlocate
- [蓝桥杯][2013年第四届真题]危险系数(暴力+dfs)
- 三、Eclipse快捷键
- mysql8.0主从配置,MySQL 8.0主从服务器(Master-Slave)配置
- mysql inode_Linux中inode的大小、作用讲述
- SpringBoot整合Redis集群版本问题
- (转)淘淘商城系列——发布dubbo服务
- java很贵可以用before代替吗_Java内存模型与Volatile,Happen-Before原则等
- Linux系统下授权MySQL账户访问指定数据库和数据库操作
- kill -9 无法杀掉进程
- 1203.1——条件语句 之 if语句
- RIP简易配置第二篇
- csdn设置资源下载所需积分
- AllWinner--R329
- json rpgmv 加密_【RPG Maker MV插件编程】【实例教程6】存档的加密解密与保护
- SwiftUI界面制作之List Navigation实现国画图文混排《潇湘卧游图》
- 千古兴亡多少事,一江春水向东流--转任总文章
- 初探 spring data(一)--- spring data 概述
- 苹果cms V10添加修改播放器教程