概述
java nio可以被称为java new io,因为其提供了一种有别于传统java io的io工作方式。同时,由于java nio是同步非阻塞的,其也被称为non-blocking io(非阻塞io)。但是,为什么java nio是同步非阻塞的?本文将对这个问题进行深入的解析。
概念解析
在对本文的问题进行分析之前,我们先看下同步异步,阻塞非则塞者两对概念。
(1)同步和异步
同步和异步描述的是一种消息通知的机制,主动等待消息返回还是被动接受消息。同步io指的是调用方通过主动等待获取调用返回的结果来获取消息通知,而异步io指的是被调用方通过某种方式(如,回调函数)来通知调用方获取消息。
(2)阻塞非阻塞
阻塞和非阻塞描述的是调用方在获取消息过程中的状态,阻塞等待还是立刻返回。阻塞io指的是调用方在获取消息的过程中会挂起阻塞,知道获取到消息,而非阻塞io指的是调用方在获取io的过程中会立刻返回而不进行挂起。
为什么java nio是同步非阻塞的?
我们知道java nio是基于io多路复用模型,也就是我们经常提到的select,poll,epoll。io 多路复用本质是同步io,其需要调用方在读写事件就绪时主动去进行读写。在java nio中,通过selector来获取就绪的事件,当selector上监听的channel中没有就绪的读写时间时,其可以直接返回,或者设置一段超时后返回。可以看出java nio可以实现非则塞,而不像传统io里必须则塞当前线程直到可读或可写。所以,java nio可以实现非阻塞。我们简单看下java nio处理连接和java socket 处理连接的方式:
//java nio
while(true) {
......
selector.select(1);
Set<SelectionKey> selectionKeySet= selector.selectedKeys();
......
//处理selectionKeySet中事件,线程没有阻塞
}
//java socket处理连接,线程会阻塞
while(true) {
......
Socket socket = serverSocket.accept();
InputStream in = socket.getInputStream();
......
//处理in中内容
}
本文篇幅很短,只是为了说明本人最近的疑虑,因为之前我一直觉得java nio也是阻塞的。希望本文可以对有相似疑虑的同学有所帮助,共同成长!