对jvm上的Kotlin来说,协程是一个用线程来实现的并发管理库
一、切线程
切到哪个线程管理是Dispatchers管理,
Dispatchers.Default: 核心线程数就是程序运行的设备的CPU的可用核心数
适用于计算密集型任务:
- 图片压缩
- 媒体编解码
Dispatcher.IO: 核心线程一般是64,当特殊设备CUP可用核心超过时会是设备的核心数,IO操作时主要是网卡或者磁盘在工作,CPU可以开启这么多个核心线程来管理应用级别的线程。
适用于IO密集型: 网络访问/文件读写
// 适用于scope.launch复用
val scope = CoroutineScope(Dispatchers.IO)
// 开启一个协程,实际在JVM上切线程
scope.launch {
}
// 或者
val scope = CoroutineScope(EmptyCoroutineContext)
// 开启一个协程,实际在JVM上切线程
// 如果CoroutineScope已经定义一种线程A,那 scope.launch里定义的线程B会覆盖A
scope.launch(Dispatchers.IO){
}
不常用的自定义线程池
//自定义线程池的尺寸
//newSingleThreadContext()单线程
val context = newFixedThreadPoolContext(4,"MyThread")
val scope1 = CoroutineScope(context)
// 使用完毕后要用close关闭线程池
//注意: 使用CoroutineScope的default和IO不需要关闭,因为系统设计他们
//是永久存活的
context.close()
二、挂起函数
gitHub.contributors在子线程执行
且gitHub.contributors在实际定义用的是suspend挂起函数
在执行挂起函数时当前函数所在协程会被挂起,即所在协程把它正在
占用的主线程给让出来,核心在于协程和线程的脱离,其中挂起函数
并没有被挂起,挂起函数做的事情是切到指定线程然后执行代码,执行完后
协程恢复,恢复即协程继续回到自己的线程去执行挂起函数后面的代码
CoroutineScope(Dispatchers.Main).launch {
val contributors = gitHub.contributors("square","retrofit")
showContributors(contributors)
}
注意: 挂起函数一定是在协程里调用的