研究线程最初的原因
[百度地图报错 java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again]
(//www.greatytc.com/p/d3dd5f2746ea)
考虑可能是APP短时间创建的线程过多,达到某些做过线程数 500 的限制的国产手机(华为、vivo),所以开始搜寻线程相关资料,开始考虑收敛线程,并做个整理记录。
原理
- 单核CPU,同一时间内,只能处理1条线程,只有1条线程在工作;多线程并发执行,其实是CPU快速地在多条线程之间调度。如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。
- 多核CPU,同一时间内,每个核可以处理1条线程 , 这才是真正的多线程并发执行,但多核CPU因为优化上会困难很多。这也是为什么苹果一直对单核CPU性能优化,而不是盲目的增加多核的原因之一,后面稍微提下为什么苹果手机 CPU 现在最多还只有4核。
是不是线程越多越好呢?
线程越多,线程之间调度消耗的资源越多,盲目的使用多线程,反而会造成整个 APP 的性能下降。哪里该用多线程,哪里不该用多线程,这个不仅仅和APP 本身相关 还和 手机硬件相关;在目前,作为程序,只要追求单核/双核CPU上的执行效率高就行了,再多的现在还体现不出来。以后,程序应该会对多核CPU进行专门的优化,要不然完全体现不出多核的优势。
专门性的对多核进行优化APP,除非是图片、视频、游戏这类,要不然意义并不大,所以对大多数程序来说,了解点多线程粗略的知识,就完全够用了。
针对不同业务线程使用也不同
CPU密集型任务是和IO密集型任务对应的,所谓CPU密集型,指的是任务是大规模的计算工作,会一直占用CPU,所以对于这类任务,线程数超过计算核心没有任何意义,因为他们很少会把线程挂起,增加线程只会导致线程直接争抢时间片和上下文切换带来的开销,所以一般来说,CPU密集型任务设计的线程池中线程个数都需要严格限制(常用计算核心数)
IO密集型任务,是我们最常见的,比如发送个网络请求,比如读写个文件,这类任务的突出特征就是对于CPU占用少,一般都会阻塞在IO设备上面,所以对于这些任务,通常我们会设置比较大的线程数量,因为反正它们执行期间大部分时间都是在睡觉,那么更多的线程可以提高系统的吞吐量。
一些语言中常见的协程,其实就是为了解决我们创建过多线程,然后其实对于CPU使用时间很短,很多线程在占用系统资源,所以在语言层面提供一种新思维,不去阻塞系统线程,在一个线程上面处理多个IO任务;
查看线程:Android系统查看某个进程的线程
参考:
RxJava优化之干掉僵尸线程
浅谈APP端多线程性能