关于java协程和kilim的一些概念

  最近了解了一下基于协程来做异步话的场景。一些基本概念写在这里。

          多任务调度方面,操作系统怎么搞的?

        一种是抢占式,指操系统给每个任务一定的执行时间片,在到达这个时间片后,如果任务仍然没有释放对CPU的占用,则操作系统强制释放,这是目前多数操作系统实现的方式。 

        一种是协作式,指操作系统按照任务的顺序来分配CPU,每个任务执行过程中除非主动释放,否则将一直占据CPU,一旦任务占据CPU不放,会导致其他任务饿死,目前操作系统不太采用这种方式。 

说完操作系统多任务调度方式后,来看看通常程序是如何实现支持高并发的,一种就是典型的给予操作系统提供的多进程或多线程机制,每个任务占据一个进程或一个线程,当任务中有IO等待等动作时,则将进程或线程放入待调度队列中,这种方式是目前大多数程序采取的方式,这种方式的坏处在于如果想支持高的并发量,就不得不创建很多的进程或线程,而进程和线程都是要消耗不少系统资源的。另一方面,进程或线程创建太多后,操作系统需要花费很多的时间在进程或线程的切换上,切换动作需要做状态保持和恢复,这也会消耗掉很多的系统资源;

另外一种方式则是每个任务不完全占据一个进程或线程,当任务执行过程中需要进行IO等待等动作时,任务则将其所占据的进程或线程释放,以便其他任务使用这个进程或线程。这种方式的好处可以减少所需要的原生的进程或线程树,并且由于操作系统不需要做进程或线程的切换,而是自行来实现任务的切换,其成本会较操作系统切换低。而这种方式也就是Coroutine方式,又称为协程方式。

这种方式我在erlang里也见过,当时对这个概念的理解也是居于编写程序的方式,

如果在JDK7里有这样的新特性,那么将会是一个很好的特性,将大大提升java的性能。

而且采用此方式,将很好的绕开需要启动太多线程来支撑高并发出现的瓶颈,提升java应用所能支撑的并发量。

网上介绍了有Scala、Kilim两种方式,根据目前网上的测试情况来看,后者表现更好一点。

        通常程序如何支持高并发?

        一种是基于操作系统提供的多进程或者多线程的机制,每个任务占据一个进程或一个线程,当任务中有IO等等待操作的时候,将进程或者线程放入调度队列,这种是目前大多数程序采用的方式,这种方式的坏处就是如果想支持高并发的并发量,不得不创建很多的进程或者线程,而进程或者线程又消耗了大量的资源。,同时大量的进程或者线程,需要花费很多时间在上下文切换上,切换动作需要做状态的保持和恢复,很是消耗资源。   

        一种是每个任务不完全占据一个进程或者线程,当任务在执行过程中,需要等待IO等资源时,任务将所占据的进程或者线程释放,以便其他任务使用这个进程或者线程,这种方式的好处在于可以减少所需要的原生的进程或者线程数,并且切换完全自行来实现,成本相对于操作系统来很低。 

        什么是协程(Coroutine)? 

        每个任务不完全占据一个进程或者线程,当任务在执行过程中,需要等待IO等资源时,任务将所占据的进程或者线程释放,以便其他任务使用这个进程或者线程。各种语言对于协程支持时,多数都采用了Actor Modle来实现,每个任务就是一个Actor,Actor之间通过消息来进行交互,而不是采用共享的方式。Actor可以看做是一个轻量级的进程或者线程。

        java和协程的关系? 

        目前java没有从语言层面支持Coroutine(Scala 和erLang有支持),kilim是基于java来实现Coroutine的框架。对于java来说,由于一个线程只能处理一个请求,即使线程中有很多IO中断、锁等也是如此。因此通用的做法是启动多个线程来支持高并发,当时线程多是,就造成了需要消耗不少时间在线程的切换上,从而出现瓶颈,按照协程的描述,理论上协程能够提升很多性能。 

          目前来看,JDK8中也不会包含协程的东西,目前比较成熟的就是kilim框架了。 

        什么场景下适合做协程序(针对java应用)? 

        只有大量的处理线程,都消耗在等待后端的处理是,做异步化才有意义,例如共计200个处理线程,其中有180多个的处理时间在等待后端处理,这种情况下,增加处理线程,如果不行再来考虑异步化改造,目前java在协程方面还不是很成熟,使用中可能遇到问题,例如锁、同步IO,都是协程的灾难。 

          Kilim框架做了啥? 

               1、利用字节码增强(基于ASM字节码框架),将普通代码转化为支持协程的代码; 

               2、调用pausable的时候,如果pause了就保存当前方法栈的State,停止执行,将控制权交给调度器; 

               3、调度器负责协调就绪的协程; 

               4、协程resume的时候,自动恢复State,回复到上次执行的位置继续执行; 

            参考文章: 

               http://www.blogjava.net/BlueDavy/archive/2010/01/28/311148.html

               http://rdc.taobao.com/team/jm/archives/326

你可能感兴趣的:(java)