这个其实看vert.x会非常清楚 vert.x里面有两个线程池(缺省)如果你自己不再开线程池的话 一个是eventloop线程池,还有一个是worker thread pool线程池 协程(coroutine)和纤程(fiber)的主要区别点在于:调度 这两个单词都翻译得不错,coop协作,co就是协的词根,coroutine翻译成协程很巧妙 fiber是纤维,翻译成纤程,对应的thread/线程,process/进程,这几个单词翻译得都比较巧妙 说回coroutine和fiber coroutine和fiber的差异点在于,两者的调度不一样,异步api在结果出来前,会释放当前线程,那么在此期间,当前线程就能去搞其他的计算活动,那一个最原始的异步api,一般是以带有callback的形式出现,但是callback有一个问题,就是写起来会变得混乱,因为callback要嵌套进参数里面去 如果多几层异步调用的话,就会形成缩进金字塔 那怎么办呢?一种解决方式就是通过声明continuation的scope,将scope里面的所有状态全部寄存,然后用continuation.yield释放当前线程,然后等结果出来之后,当前线程再从寄存器里取出状态,继续往前执行 那这里有几个问题,不一一列举,有兴趣的自己去搞懂这里面的机制,建议多看vert.x 有一个最重要的差别点就是,当这个结果出来之后,后续的代码,是由哪个线程在执行? **如果还是原来线程在执行,那么就是coroutine** **如果存在有被其他线程所执行的可能,那就是fiber** 这里可以看出来,fiber多了一个调度器,scheduler,所以一般fiber在启动的时候,会开一个carrier thread pool,线程池,大多数语言叫这个线程池叫做fork & join pool,既然是pool,那里面的线程不止一个,那fiber如果使用了异步操作,这里就**有可能**被一个以上的线程先后执行,注意这里是有可能,因为调度器有可能会把后续的步骤调度回原来的线程,但是这个完全由调度器决定 那这样做的好处是什么呢?客户在这里使用blocking code,因为这个流程基本上**完全模拟**了线程操作,线程在io时候是怎样被blocked,这里的纤程也会怎样被blocked 坏处是什么呢?嗯,跟线程一样,它需要一个完美的stack,线程就有自己的stack,那这个stack可能会比线程的stack要小,但是会比coroutine的stack要大很多,同时调度上也有一定程度的消耗,当然这个消耗可能不大,但还是有,因为可能被其他线程所执行,所以要在yield之前,把当前线程的所有状态全部寄存,否则resume的时候,状态丢了就完蛋了 那coroutine呢?coroutine则保证会使用原来的线程,所以会有eventloop的概念,node.js就用了eventloop,还有vert.x,那因为是原来的线程,那这里会有问题,一个是线程可能过度负荷,导致一个线程在忙,其他线程在观望的情况,所以这就出现了eventloop的一个坏处 那就是,你需要估算eventloop的执行时间,不能让它被blocked,这就对程序员提出了更高的心智要求 好处是什么呢?性能 因为都是同一个线程在执行,那么yield的时候,需要保存的状态就少了很多,kotlin里面一个coroutine的消耗才区区几百个字节,一般的fiber做不到这么低 同时因为调度的都是原来的线程,所以调度的损耗也减少了,所以总体而言,coroutine+eventloop的性能,要高过fiber+fork&join pool的性能,但是同时,对开发人员的心智要求,也相应提高了 说一下java的进度,java的loom正在如火如荼地开展中,vert.x已经实现了eventloop pool,但是目前java的语法,还只能实现future(monad)和callback两种api,还做不到await和scheduler,因为这两者的实现,都需要project loom的continuation yield/scope和scheduler这些,但是我们已经可以在kotlin中先行体验coroutine,其实也有fiber,用launch(common pool)加上缺省的调度器,就是fiber了 同时clojure也提供了core.async,也提供了fiber,缺省用的就是fork&join pool 所以还是要搞vert.x,否则这两者你没有办法完全体验到,像node,只有eventloop和await,没有fiber,像go就是强制使用goroutine(就是fiber),就没有coroutine,一般的java工具,还停留在thread阶段,只有vert.x这种多语言的工具,可以提前接触kotlin等语言,这些概念就都会出现 * * * 刚看到一个相关问题,应该说c++的boost是最早的fiber和coroutine的出处了 虽然不是java,但是java的概念也从中延伸而来,这个问题的高票答案也说到了 fiber带了一个调度器,coroutine则不带,java一样的