本质概念不同编程语言选择不同并发模型java用线程kotlin使用协程。jvm实现特点线程实现所以底层还是通过线程实现的只是封装线程提供了更友好的api来管理并发。kotlin是上层语言核心特性协程不绑定线程可以在一个线程挂起然后在另一个线程恢复执行。协程比线程的优势 好用可以用线性结构来写异步代码切换线程之后还可以自动切回来。 java原来处理线程切换需要写回调kotlin语言特性 小驼峰是方法大驼峰是类切线程 异步执行不想卡住当前线程、客户端必须切回UI线程执行Default是用来处理计算密集型的任务即不跟外界交互的都是计算密集型IO 跟内存之外的数据交互磁盘或网络http网络请求之类的Main: 客户端存在服务端不存在协程上下文 可以指定线程池对象上下文需要记得关闭避免资源占用。默认的调度器的上下文因为是全局的所以不用手动关闭。协程作用域 创建一个协程作用域然后再launch执行任务。通常都是创建主线程的协程然后协程内通过挂起函数来切到后台线程去执行任务后续会自动切回主线程。这个套路是针对UI来做的挂起函数 执行挂起函数时调用处的协程就会被挂起等待/暂停所谓协程挂起就是不再占用协程所在的线程。在协程内可以再次挂起切换到其他协程。挂起函数需要在协程里或者另一个挂起函数里调用。挂起函数会自动切回协程所以就不用写回调了。挂起函数为什么不阻塞线程Android的jetpack库里面有一些针对kotlin语言特性的扩展也就是ktx比如可以直接可用的scopelifecycleScope跟页面生命周期绑定在onDestroy时自动关闭协程。viewModelScope在viewMode中使用。withContext并行协程 这里会不等IO里的协程执行完就执行println如果要串行执行则要使用suspend挂起函数把协程给挂起后续流程先别开始,具体用到withContext可以进一步抽取到suspend函数因为是调用了挂起函数所以才加的suspend也才具备在函数内调用其他挂起函数。同时挂起函数也被限制只能在协程或者其他挂起函数里调用作用范围被缩窄了。IDE让你加suspend的时候再加。耗时操作抽取到函数里可以同时把withContext也一起抽取因为耗时任务是注定和io或者default绑定的计算密集型、IO型挂起函数为什么不卡线程主线程无限循环子线程执行完回调都到主线程所以不会阻塞客户端程序的UI线程会无限循环因为要做到界面刷新所以可以做到线程切换。HandlerThread是一种特殊的线程会无限循环、任务队列。runBlocking是单线程的内部launch启动的所有协程都是在同一个线程里执行的。Thread.sleep是锁住当前线程而delay是挂起函数只是让出当前线程来延时则不会造成性能浪费。模拟耗时任务需要使用Thread.sleep因为这是真的把线程占住了。结构化并发 structured concurreny通过CoroutineScope来启动协程的。Android内存泄漏、弱引用、活跃线程导致内存泄漏 -》 非活跃线程之后则不会一直内存泄漏。rxjava是一个链式调用。每个协程的启动都返回了job类型对象可以调用cancel取消协程job是取消一个协程scope是取消作用域里启动的所有协程。里面的scope是受到外面的scope管理的可以管理子协程、子子协程等等管理多层协程。并行协程的启动和交互除了launch可以启动协程还有async可以启动。还有个比较特殊是runBlocking。async是有返回值的是一个Deferred, T是泛型返回。并行才使用async并行请求示例其实也可以启动两个async最后使用一个launch来同时await等待。还可以更简洁写法在launch里启动async 然后使用await获取结果再回顾下面下面是launch 挂起函数所以是串行join会等待挂起对应的协程执行完才继续执行协程和线程的连接 可以把回调式调用改成协程格式suspendCoroutine以及suspendCancellableCoroutine是可以取消的正常都是使用后者如下把回调格式的调用改成协程调用通过suspendCoroutine以及it.resume()可以拿到返回值如下是捕获不到异常的因为launch启动这个操作早已完成挂起函数可以配合协程的取消行为但是线程sleep做不到。runBlocking 阻塞当前线程、并在当前线程执行CoroutineScope作用;指定上下文以及可取消。而runBlocking不需要这两个所以不需要使用scope启动另外runBlocking会阻塞线程corouyineScope函数是在协程内部提供结构化的作用域