前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android面试题之Kotlin协程到底是什么?它是线程吗?

Android面试题之Kotlin协程到底是什么?它是线程吗?

作者头像
AntDream
发布2024-06-13 21:04:21
600
发布2024-06-13 21:04:21
举报

协程是什么?

协程是线程吗?是线程池的线程?是轻量级的线程?

实际上,可以非常肯定的说,协程不是线程!

那既然协程不是线程,那又为什么常说协程是轻量级的线程呢?协程轻在哪呢?

"轻量级"的线程

Kotlin中的协程经常被称为“轻量级线程”,这是相对于传统的线程模型而言的。为了更好地理解这一点,我们需要从内存占用、任务切换、JVM内存模型等多方面进行剖析。

1. 轻量级的原因

1.1 内存占用
  • 线程: 每个线程在创建时分配一定数量的栈内存(默认大约1MB)。如果系统启动大量线程,则会消耗大量内存,可能导致系统资源枯竭。
  • 协程: 协程是运行在现有线程中的,它们不需要单独的栈内存,而是共享调用栈。这样使协程仅有少量内存开销,通常每个协程只占用几个KB。这使得同一线程可以管理和运行大量协程,不受传统线程数量限制。
1.2 任务切换
  • 线程切换: 线程切换由操作系统管理,涉及到用户态和内核态之间的切换,代价较高,需要保存和恢复CPU寄存器、程序计数器、内存栈等。
  • 协程切换: 协程切换在用户态完成,不涉及内核态切换,只是切换函数的上下文,代价相对低很多。

2. 内存模型

2.1 线程内存模型

在JVM中,每个线程都有自己独立的线程栈,每个栈帧包含局部变量、操作数栈和相关信息。当线程被挂起时,所有这些信息必须保存并在重新调度时恢复。

2.2 协程内存模型

协程的栈帧通常是堆上的对象,当协程挂起时,不需要切换线程,只是函数调用的上下文发生变化,把协程状态保存到堆中。这种模型使得内存利用更加高效和灵活。

2.3 协程堆栈帧

协程在挂起时,会将当前的堆栈帧转换为对象并存储在堆中。这个对象包含了所有当前帧的局部变量、挂起点以及其他必要信息。恢复时,这个对象重新转换为堆栈帧并继续执行。

2.4 Continuation

Kotlin中的挂起函数实质上会被编译器转换成带有回调的 Continuation 对象。该对象包含两个主要部分:

  • 上下文(Continuation Context):绑定的执行环境。
  • 恢复逻辑(Resume Logic):保存和处理挂起点的逻辑。
代码语言:javascript
复制
interface Continuation<in T> {
    val context: CoroutineContext
    fun resumeWith(result: Result<T>)
}

3. 执行机制

3.1 线程

线程由操作系统调度,执行时获得CPU时间片,可能被抢占。这一过程完全由操作系统管理,且每次线程切换都会导致上下文切换,引入显著的开销。

3.2 协程

协程仅占用一个线程的部分时间,是由协程库(例如 kotlinx.coroutines)管理。一个线程可以执行多个协程,只要它们异步工作并时常挂起和恢复。这大大减少了切换开销,改善性能。

4. 协程例子

代码语言:javascript
复制
import kotlinx.coroutines.*

fun main() = runBlocking {
    repeat(100_000) {
        launch {
            delay(1000L)
            println("Coroutine $it is done")
        }
    }
}

在这个例子中,启动了10万协程,但内存占用远远小于10万个线程,且切换效率高。这是因为:

  • 非阻塞挂起: delay 使得协程挂起,但不阻塞线程,使得同一线程可以继续处理其他协程。
  • 上下文保存和恢复: 协程的上下文切换只需要保存和恢复堆上的对象状态,代价低。

由于协程不阻塞线程,上面的例子中,日志几乎是同时打印的

总结

Kotlin 协程的轻,主要原因包括:

  1. 内存占用更少:协程不需要独立的栈内存,而是共享调用栈。
  2. 低切换开销:协程切换在用户态完成,无需与操作系统交互,开销小。
  3. 高并发模型:在同一线程上可以高效地运行大量协程,不受传统线程创建管理的限制。

协程是更高层的抽象,它方便我们开发的同时也带来了理解的困难,对于协程,你是怎么看的呢?欢迎留言交流讨论

码字不易,求转发,求点在看,求关注,感谢!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AntDream 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 协程是什么?
  • "轻量级"的线程
    • 1. 轻量级的原因
      • 1.1 内存占用
      • 1.2 任务切换
    • 2. 内存模型
      • 2.1 线程内存模型
      • 2.2 协程内存模型
      • 2.3 协程堆栈帧
      • 2.4 Continuation
    • 3. 执行机制
      • 3.1 线程
      • 3.2 协程
    • 4. 协程例子
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档