JAVA的I/O发展史

JDK1.0到JDK1.3,最为原始的BIO;
2002年发布的JDK1.4提供了NIO(多路复用I/O);
2011年正式发布的JDK1.7提供了NIO2.0,其支持AIO功能。

I/O模型

《UNIX网络编程:卷一》第六章——I/O复用。书中向我们提及了5种类UNIX下可用的I/O模型:

  • 阻塞式I/O;
  • 非阻塞式I/O;
  • I/O复用(select,poll,epoll…);
  • 信号驱动式I/O(SIGIO);
  • 异步I/O(POSIX的aio_系列函数);

其实前四种I/O模型都是同步I/O操作,他们的区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。

阻塞式I/O模型

默认情况下,所有套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操作通常包括两个不同阶段:

  1. 等待数据准备好,即数据被复制到内核中某个缓冲区;
  2. 从内核向应用进程复制数据。

个人关于阻塞和非阻塞的区别:进程/线程是否需要等待要访问的数据。

同步和异步

POSIX对这同步和异步的定义:

  • 同步I/O操作:导致请求进程阻塞,直到I/O操作完成;
  • 异步I/O操作:不导致请求进程阻塞。

关于epoll

虽然把epoll归属于I/O复用这个模型中,但它却比较特殊:

  • select和poll是在内核层通过轮询socket句柄的方式来实现的,而epoll采用了更加底层了notify 机制, 而不是肓目地轮询来实现, 这样减少了内核层的CPU消耗。
  • select和poll在第二个阶段在中会被阻塞直到数据复制完成,而epoll因采用mmap的机制使得内核socket buffer和用户空间的buffer共享而不会被阻塞。

SO,epoll是同步IO吗?


同步与异步、阻塞与非阻塞。不要两两结合产生4组名词,这是条歪路。