Java NIO
一句话总结:Java NIO主要解决传统IO针对每个连接都需创建一个阻塞线程,造成大量线程时线程上下文的开销。NIO通过一个独立单线程管理连接,当数据到达时触发事件,业务可自由选择单线程/线程池/新线程进行处理。这在有大量连接但数据传输不频繁的场景如IM聊天场景非常有用。
Java NIO的几个重要概念:
1、Channel和缓冲区
传统IO是基于流Stream的,包括字节流和字符流,NIO是基于通道Channel的。流是单向的,InputStream和OutputStream分开,Channel是双向的,既可以读数据,也可以写数据。传统IO可选择性的使用缓冲,而NIO必须使用缓冲区。注意,NIO使用自定义长度缓冲区,会使其处理数据比传统IO较复杂。
2、异步、非阻塞和Selector
通过ServerSockerChannel(或其他服务器端)监听端口,此服务器会为每一个连接分配一个Channel。该服务器端需要注册选择器(JDK提供无需我们实现)和事件。当前有connect/accept/read/write四种事件。注册完后我们就可以通过选择器的select()方法来等待事件通知及处理事件。
Reactor设计模式
这里我们通过生活场景来模拟NIO的设计,便于我们理解和记忆。
传统IO:有个饭馆服务很好,每个客人来了,都安排一个美女服务员接待。客人多了,需要的美女服务员也多了,开销变大。
NIO:客人来了,美女服务员接待,客人花了10分钟点菜,此时美女服务员阻塞在那等着。老板很聪明发现可以优化,专门安排一个协调员,客人点菜这段时间,美女服务员先忙其他的,客人点完菜按下桌玲,协调员听到铃声再安排美女服务员进行接待。
备注:这里的美女服务员就是业务线程,可以把美女服务员看做点菜、厨师、上菜等一整个业务流程。协调员就是Selector。
备注:这里不介绍NIO的具体使用代码,通常我们会通过Netty框架来处理。固我们只需要了解NIO设计思想及原理即可。