NIO非阻塞编程的简单介绍

什么是NIO?

NIO所在的包是java.nio。其中的n表示non-blocking。但是实际上我们可以把它理解成nio=net+io,因为NIO包实现了网络通讯和io的联合功能,并且将他们结合发挥到极致,实现了完美的非阻塞通讯功能。如图所示:

为什么会有NIO?

因为普通的socket通讯存在着I/O问题----阻塞通讯,并且分析传统的解决方法----线程池的优缺点,进而引进NIO的解决方案。

1基于Socket通讯的存在的问题----I/O阻塞通信

经典的网络服务器的结构的通讯过程:

方框内的操作会循环执行,并且监听连接、读取数据、写入数据这些操作都是阻塞的。在其ServerSocket操作的具体如下:

1 Socket socket = ss.accept();     //这里是阻塞的

2  BufferReader br  = new BufferReader(new InputStrameReader(socket.getInputStream()));

    PrintWriter pw = new PrintWriter(socket.getOutputStream());

    //读写数据

    String line;

    while(line==br.readline()!=null){          //读阻塞

         os.println(line);                               //写阻塞

         os.flush();

    }

在Jdk1.4之前解决这个问题是利用线程池的方法来解决的,服务器启动的时候创建一个线程池,当监听到客户端连接时,就为客户端从线程池取出一个线程,当客户端断开连接时,该客户端就会将该线程归还到线程池中,以提高线程池的使用效率。

虽然线程池可以使服务器处理多个连接,但是每个线程拥有自己的栈空间并且浪费大量的cpu时间,消耗比较大,而且很多时间是浪费在阻塞的I/O操作上,没有有效的利用CPU。

所以最新解决方式是----NIO 非阻塞通信

如何用NIO?

首先需要理解NIO的四个核心框架

1 缓存Buffer:它是包含数据且用于读写的线性表结构。其中还提供了一个特殊的类用于内存映射文件的I/O操作。

2 字符集Charset:提供了Unicode字符串影射到字节序列及逆影射的操作。

3 通道Channel:包含Socket、File和Pipe这三个管道,它实际上是双向交流的通道。

4 选择器Selector:将多元异步I/O操作集中到一个或多个线程中。

(下次会详细的解释这四种核心框架)

然后了解一下NIO通道编程:简单了解一下四种通道类编程(具体下次详细介绍)

1 文件通道FileChannel:用于实现对文件的读取、写入、锁定和映射

2 Socket通道SocketChannel:实现基于Socket通道

3 ServerSocket通道ServerSocket:实现基于ServerSocket通道

4 数据报通道DatagramChannel:实现基于DatagramChannel通道

 

NIO的非阻塞I/O机制是围绕选择器和通道构建的。Channel类表示服务器和客户端之间的一种通讯机制。与反应器模式一致。Selector类是Channel的多路复用器。Selector类将传入客户机请求的多路分用。并且将他们分派到各自的请求处理程序,实现客户端请求事件的非阻塞监听

在椭圆区域中,Selector监听器负责轮询客户端的连接、读取和写入事件,这些事件执行都不会被阻塞,并且提高执行效率,NIO读取和写入事件都使用了缓存区。