目录
多线程操作分类
- 切线程
- 线程在执行过程中等待别的线程
- 互斥锁、线程安全
一、概念
1.协程(Co routine)是轻量级线程,是线程框架(扔物线表述)。
2.用来处理耗时任务,保证主线程安全。
3.线程运行在内核态,而协程运行在用户态。
以同步的方式写异步代码,避免回调地狱,比如java用retrofit进行网络请求,再利用请求结果进行一个网络请求,就会回调里面嵌套回调。
最核心的就是挂起,suspend,能让程序被挂起,运行完后在挂起的位置恢复。也就是不再占用这个函数正在工作的线程 。挂起函数可以嵌套,只能在协程里面执行。
协程调度器(Dispatcher)
协程需要在调度器上运行。
Dispatchers.Main 主线程,处理ui和轻量级任务
Dispatchers.IO IO线程,网络读写、文件读写、数据库读写
Dispatchers.Default CPU密集任务,json解析、数组排序
还有一个不常用。
简单来说,如果网络请求和磁盘操作,就用IO,其余计算如图片压缩,编解码等用Default。
协程构建器
launch
async
都是job类型,async 可以返回一个结果,可以通过任务.await来获取。
launch让协程先执行,可以通过join来抢占,而async是通过await(),都是挂起函数,不会阻塞主线程。
协程作用域
协程作用域 CoroutineScope 是一个接口,没有任何抽象方法需要实现,仅仅维护一个成员变量 CoroutineContext(协程上下文)
二、使用
协程需要运行在
协程上下文环境,在非协程环境中凭空启动协程,有三种方式
runBlocking{}
启动一个新协程,并阻塞当前线程,直到其内部所有逻辑及子协程逻辑全部执行完成。不推荐。
GlobalScope.launch{}
协程生命周期和应用程序一样,不推荐。
CoroutineScope + launch{}
为自己的组件实现CoroutieScope接口,在需要的地方使用launch{}方法启动协程。使得协程和该组件生命周期绑定,组件销毁时,协程一并销毁。从而实现安全可靠地协程调用。推荐。
类似java线程池,但是更大一点。
使用:创一个对象,调用launch启动线程,再可以选择调度器进行切线程。
Jetpack提供给我们的作用域,给我们包装了在主线程的协程。
具体来说,是Main.immediate。比Main更好,如果已经在主线程,就直接执行。
在Activity或Fragment中,用 lifecycleScope ,跟当前所在组件的生命周期绑定。
如果在ViewModel中,用 viewModelScope 。
WithContext
Launch是并行地切线程,如果我们需要串行地切线程,比如让一个函数先执行,就用withContext和调度器连用。
自定义挂起函数
应该从函数里面的代码是否需要挂起来思考。
其他
挂起函数在编译过程进行了一个处理,本质其实也是回调,进行了一个切线程。
不能从主线程切到指定的子线程,不管是服务端还是客户端。
客户端的话,主线程下执行网络请求,下面一行等待数据进行处理,不会阻塞主线程,因为其实没有一直在等回调,而是无限循环,刷新ui。或许是16ms?一帧。等网络请求得到数据了,下一行代码才被抛到消息队列里面进行执行。
&spm=1001.2101.3001.5002&articleId=140111814&d=1&t=3&u=6df25122dc884357bb31ae8380684bf4)
4746

被折叠的 条评论
为什么被折叠?



