并发之网络NIO

NIO是new IO的简称,是一种可以替代Java IO的新的IO机制,它提供了一套不同于Java IO的机制。NIO和并发并无直接关系,但使用NIO可以大大提高线程的使用效率。对于标准的网络IO来说,一般使用socket进行网络的读写。为了让服务器可以支持更多的客户端连接,通常做法是为每一个客户端连接开启一个线程。

1、基于socket服务端的多线程模式

服务器会为每个客户端连接启用一个线程,这个新的线程将会为这个客户端服务,同时为了接受客户端连接,服务器还好额外使用一个派发线程。

echo服务端示例
echo客户端连接示例
服务端结果
客户端结果

这种多线程的服务器开发模式很常用,对于大多数应用来说此模式可以很好的工作,但其有个重大弱点:它倾向于让CPU进行IO等待。

服务端结果
客户端结果

对于服务端,每个请求的处理时间都在6秒左右,因为服务端需要先读入客户端的输入,而客户端缓慢的处理速度使得服务器花费了不少等待时间。当服务器需要处理大量的请求连接,每个请求都拖慢了服务器的处理速度,则服务器能够处理的并发数量就会大幅度减少。

2、使用NIO进行网络编程

使用Java的NIO可以将上例中网络IO的等待时间从业务处理线程中抽取出来。

NIO的组件:

Channel(通道):它类似于流,一个Channel可以喝文件或网络Socket对应,如果Channel对应着一个Socket,则往这个Channel中写入数据,就等同于向Socket中写入数据。

Buffer:可以把它理解成一个内存区或byte数组,数据需要包装成Buffer形式才能和Channel交互。

Selector(选择器):在Channel的实现中,有一个SelectableChannel实现,表示可以被选中的通道。任何一个SelectableChannel都可以将自己注册到一个Selector中,这样这个Channel就能被Selector管理。一个Selector可以管理多个SelectableChannel。当SelectableChannel的数据准备好时,Selector就会接到通知,得到那些已经准备好的数据,SocketChannel是SelectableChannel中的一种。

一个Selector可以由一个线程进行管理,而一个SocketChannel可以表示一个客户端连接,这就构成了由一个或极少数线程,来处理大量客户端连接的结构。当与客户端连接的数据没有准备好时,Selector会处于等待状态,一旦有任何一个SocketChannel准备好了数据,Selector就能立即得到通知,获取数据进行处理。

使用NIO实现服务端
使用NIO实现服务端
使用NIO实现服务端
使用NIO实现服务端
服务端运行结果

3、使用NIO实现客户端

使用NIO实现客户端
使用NIO实现客户端


--参考文献《实战Java高并发程序设计》

你可能感兴趣的:(并发之网络NIO)