1. 同步阻塞IO
在阻塞IO模型中,Java应用程序从IO系统调用开始,直到系统调用返回,在这段时间内,Java进程是阻塞的,返回成功后,应用程序才开始处理用户空间的缓存区数据。
优点:开发快。缺点:一个线程维护一个IO连接,在并发量高的情况下,内存、线程切换开销非常大
2. 同步非阻塞NIO
在NIO模型中,会出现下面两种情况:
- 在内核缓冲区中没有数据的情况下,系统调用会立即返回一个调用失败的信息
- 在内核缓冲器有数据的情况下,是阻塞的,直到数据从内核缓冲区复制到用户进程缓冲。复制完成后,系统调用返回成功,应用进程开始处理用户空间的缓存数据
应用程序需要不断进行IO系统调用,轮询数据是否已经准备好,如果没有准备好,就继续轮询,直到完成IO系统调用为止。
优点:每次发起IO调用,在内核等待数据过程中可以立即返回,用户线程不会阻塞,实时性好
缺点:不但轮询内核,会占用大量CPU时间
3. IO多路复用模型
一个进程监视多个文件描述符,一旦某个描述符就绪,内核就将就绪的状态返回给应用程序。随后,应用程序根据就绪的状态,进行相应的IO系统调用
优点:一个选择器查询线程可以同时处理成千上万个连接,系统不必要创建大量线程,也不必要维护这些线程,减小系统开销
缺点:本质上,select/epoll调用是阻塞的,属于同步IO,都需要在读写时间就绪后,由系统调用本身负责进行读写,这个过程是阻塞的
4. 异步IO模型AIO
用户线程通过系统调用,向内核注册某个IO操作。内核在整个IO操作完成后,通知用户程序,用户执行后续业务操作。
优点:在内核等待数据和复制数据这两个阶段,用户线程都不是阻塞的,用户线程需要接收内核的IO操作完成的事件,或者用户线程需要注册一个IO操作完成的回调函数。
缺点:应用程序仅需要进行事件的注册和接受,其余工作需要操作系统的支持
|