BIO、NIO与SELCT
BIO
同步阻塞模型,在socket( , bind( , listen( 后,会执行accept等待链接,连接后才能继续下一个accept,在接收到accept之后,会执行R/W,这个过程也会有阻塞,我们要抛出线程,不让他阻塞当前线程,这个过程中产生系统调用,所以这种方式最慢。
NIO
同步非阻塞模型,在socket( , bind( 后会执行NONBLOCKING操作,这个过程将accept设置为非阻塞,如果程序执行了accept,没有链接的时候,操作系统返回-1,Java返回null,可以不用阻塞,直接进行下一次accept,然后将接收到的client放入一个链表,在循环处理所有的链表执行R/W。
select、poll
同步非阻塞模型,在执行上面的操作后,我将所有的IO用一个select管理,在系统调用select的时候,由内核调用所有IO去获得可以进行R/W操作的IO,并返回给app。比NIO少的就在于NIO是由用户程序调用该IO是否是R/W的,会有一个由用户态到内核态切换的系统调用,而select是由内核态完成的遍历,只需要调用一次系统调用select()即可。
epoll
同步非阻塞模型,要知道每一个IO都会产生一个IO中断,当client发送一个数据包过来以后,会在网卡的buffer中存储数据,在epoll之前的所有模型中,产生中断后,中断的回调函数只是将网卡的buffer中的数据关联到IO的buffer中去;而在epoll模型中,产生中断后,回调函数会开辟一个红黑树,不仅将网卡的buffer关联到IO的buffer中,还会执行一次把能R/W的IO存进去,这样Java调用select()的时候,只调用一次epoll_wait即可获得所有已经能R/W的IO。