Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-11-18:请谈谈Kotlin中的Coroutines,它与线程有什么区别?有哪些优点?

Moosphan opened this issue · comments

在程序运行过程中某些操作(像是:网络IO、文件IO、CPU或GUP计算密集型工作等等)可能会耗费大量的时间,在单线程的环境下可能会造成线程的阻塞,在他们完成之前没办去做其它事情。

使用传统方法的话,我们可能会选择使用多线程来解决这个问题,将这些耗时操作放置到新的线程中去执行,使主线程能够正常的运行。那么本文标题所提到的协程是怎么一回事呢?

协程可以看作是一个轻量级的线程,他不是由操作系统或是虚拟机来实现的,而是通过编译器。这意味着相对于线程,协程的开销更小。大家可以从下面的这个例子中感受一下

下面是一段Kotlin使用协程的代码,创建了100万个协程 (官方的例子是使用的100K,不过运行时间太短,不好截内存的使用情况)。

fun main(args: Array)= runBlocking { val jobs= List(1_000_000){
launch(CommonPool){
delay(10L)
println(it)
}
}
jobs.forEach { it.join() }
}

commented

其实没什么区别,协程的本质也是线程,是 kotlin 为开发者设计的一套语法糖,用起来更简单而已。
在底层效率上没有区别,所以不存在 比线程轻量级 的说法。

嗯,这个可以这么理解,Coroutines 本身就是一个轻量级的线程,简单来说协程是一个非抢占式或者说协作式的计算机程序并发调度的实现(手动问好脸),什么是轻量级的呢?这个就要和线程对比理解了,我们常见的大多数线程,以操作系统方面来说线程是映射到内核的线程的,也就是说线程中代码的逻辑在线程抢到CPU资源的时间时才可以执行,否则就是歇着,那么Coroutines说是一个轻量级的线程的意思是,Coroutines并不会映射程内核的线程或者其他重资源,他的调度在用户态就可以搞定,任务之间的调度并非是抢占式的,而是协作式的,Coroutines可以主动挂起和恢复执行,所以说Coroutines是轻量级的线程,优点:可以替换回调地狱、解决RxJava这类复杂的调度逻辑、替换线程(Android 开发中耗费资源的任务需要在线程中执行,然而只能在UI线程更新,Coroutines可以通过上下文切换线程,既可以执行耗时任务也可以更新UI线程)、在和Retrofit等框架配合使用、可以通过拦截上下文、自定义拦截器等实现很多想要的东西

commented

说一下个人理解吧。先列出协程几个特点:
1,在单个进程内,多个协程串行执行,只挂起不阻塞
2,协程最终的执行还是在各个线程之中

优点:
1,由于不阻塞线程,异步任务是编译器主动交到线程池中执行。因此,在异步任务执行上,切换和消耗的资源都较少。
2,由于协程是跨多个线程,并且能够保持串行执行;因此,在处理多并发的情况上,能够比锁更轻量级。通过状态量实现

commented

其实没什么区别,协程的本质也是线程,是 kotlin 为开发者设计的一套语法糖,用起来更简单而已。
在底层效率上没有区别,所以不存在 比线程轻量级 的说法。

简短精悍。也就是跑在固定的几个线程,虽然启动了成千上百万个协程,时间上只运行了最多4-8个线程执行这些任务而已