kotlin协程

Kotlin中的协程是什么

协程能做的,Java线程都能够做,kotlin协程只是一套封装较好的java线程api。

为什么需要引入协程?

  • 节省资源,轻量,无非就是
    • 节省内存,每个线程都需要分配一段栈内存,以及其他一些资源。
    • 节省分配线程的开销,创建和销毁都要进行系统调用
    • 大量线程切换带来的开销
  • 与nio配合实现非阻塞的编程,提高系统的吞吐、
  • 使用起来更加顺畅,跑起来是异步的,写起来是同步的。

分别来看,web中,tomcat线程数量一般在50-500,spring默认给200。假如每个线程128kb,500个线程才多大呢?

在看分配线程的开销,Java线程池可以很好的解决问题,vertx、kotlin协程本质都是使用线程池实现的,又有多少开销呢?

线程的切换实际只会发生在活跃的线程上,在web场景中,大量的请求会因为io(发请求、db)挂起,根本不会参与操作系统的线程切换,为了减少线程切换的开销,真正要防范的是同时有大量活跃线程

再说 nio,Java NIO/Netty/Vert.X/rxJava/Akka可以任意选择。一般来讲,Netty可以解决绝大部分因为IO的等待造成资源浪费的问题

Java仅仅是没有解决”协程“在Java中的定义,以及“写得优雅“这个问题。

什么时候适合用协程

线程调度是被动调度,协程调度是主动调度。

在传统Java线程中,如果想要跑满CPU,在一些高并发,io密集型场景中,其效率不如协程。因为线程模型在遇到需要等待的地方时(如 io),并不会主动交出线程,需要创建更多线程来抢占CPU时间片,Java线程模型是1:1的,会创建大量操作系统级线程,并由操作系统进行管理调度,调度时机是随机的,频繁的调度会产生不小的开销。

而协程的调度是用户态进程内runtime管理的,这个过程没有操作系统的线程调度的干预,这就需要协程主动交出执行权,通常就是io。

如果是纯计算场景,程序中无需等待,线程又不是很多,那完全使用线程就足够了。