文档章节

14. Java NIO vs IO

逝去的回忆
 逝去的回忆
发布于 2016/11/19 17:07
字数 1187
阅读 9
收藏 0

当学习Java的NIO和IO时,有个问题会跳入脑海当中:什么时候该用IO,什么时候用NIO?

下面的章节中笔者会试着分享一些线索,包括两者之间的区别,使用场景以及他们是如何影响代码设计的。

NIO和IO之间的主要差异(Mian Differences Between Java NIO and IO)

下面这个表格概括了NIO和IO的主要差异。我们会针对每个差异进行解释。

IO NIO
Stream oriented Buffer oriented
Blocking IO No blocking IO
  Selectors

面向流和面向缓冲区比较(Stream Oriented vs. Buffer Oriented)

第一个重大差异是IO是面向流的,而NIO是面向缓存区的。这句话是什么意思呢?

Java IO面向流意思是我们每次从流当中读取一个或多个字节。怎么处理读取到的字节是我们自己的事情。他们不会再任何地方缓存。再有就是我们不能在流数据中向前后移动。如果需要向前后移动读取位置,那么我们需要首先为它创建一个缓存区。

Java NIO是面向缓冲区的,这有些细微差异。数据是被读取到缓存当中以便后续加工。我们可以在缓存中向向后移动。这个特性给我们处理数据提供了更大的弹性空间。当然我们任然需要在使用数据前检查缓存中是否包含我们需要的所有数据。另外需要确保在往缓存中写入数据时避免覆盖了已经写入但是还未被处理的数据。

阻塞和非阻塞IO比较(Blocking vs. No-blocking IO)

Java IO的各种流都是阻塞的。这意味着一个线程一旦调用了read(),write()方法,那么该线程就被阻塞住了,知道读取到数据或者数据完整写入了。在此期间线程不能做其他任何事情。

Java NIO的非阻塞模式使得线程可以通过channel来读数据,并且是返回当前已有的数据,或者什么都不返回如果但钱没有数据可读的话。这样一来线程不会被阻塞住,它可以继续向下执行。

通常线程在调用非阻塞操作后,会通知处理其他channel上的IO操作。因此一个线程可以管理多个channel的输入输出。

Selectors

Java NIO的selector允许一个单一线程监听多个channel输入。我们可以注册多个channel到selector上,然后然后用一个线程来挑出一个处于可读或者可写状态的channel。selector机制使得单线程管理过个channel变得容易。

NIO和IO是如何影响程序设计的(How NIO and IO Influences Application Design)

开发中选择NIO或者IO会在多方面影响程序设计:

  1. 使用NIO、IO的API调用类
  2. 数据处理
  3. 处理数据需要的线程数

API调用(The API Calls)

显而易见使用NIO的API接口和使用IO时是不同的。不同于直接冲InputStream读取字节,我们的数据需要先写入到buffer中,然后再从buffer中处理它们。

数据处理(The Processing of Data)

数据的处理方式也随着是NIO或IO而异。 在IO设计中,我们从InputStream或者Reader中读取字节。假设我们现在需要处理一个按行排列的文本数据,如下:

Name: Anna
Age: 25
Email: anna@mailserver.com
Phone: 1234567890

这个处理文本行的过程大概是这样的:

InputStream input = ... ; // get the InputStream from the client socket

BufferedReader reader = new BufferedReader(new InputStreamReader(input));

String nameLine   = reader.readLine();
String ageLine    = reader.readLine();
String emailLine  = reader.readLine();
String phoneLine  = reader.readLine();

小结

NIO允许我们只用一条线程来管理多个通道(网络连接或文件),随之而来的代价是解析数据相对于阻塞流来说可能会变得更加的复杂。

如果你需要同时管理成千上万的链接,这些链接只发送少量数据,例如聊天服务器,用NIO来实现这个服务器是有优势的。类似的,如果你需要维持大量的链接,例如P2P网络,用单线程来管理这些 链接也是有优势的。这种单线程多连接的设计可以用下图描述:

nio-vs-io-3.png

Java NIO: A single thread managing multiple connections

如果链接数不是很多,但是每个链接的占用较大带宽,每次都要发送大量数据,那么使用传统的IO设计服务器可能是最好的选择。下面是经典IO服务设计图:

nio-vs-io-4.png

Java IO: A classic IO server design - one connection handled by one thread.

© 著作权归作者所有

共有 人打赏支持
逝去的回忆
粉丝 13
博文 136
码字总数 219872
作品 0
深圳
高级程序员
私信 提问
Java NIO系列教程(十二) Java NIO与IO

原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我...

_夏天的风_
2013/07/11
0
0
分别使用Java IO、NIO、Netty实现的一个Echo Server示例

分别使用Java IO、Java NIO、Netty来实现一个简单的EchoServer(即原样返回客户端的输入信息)。 Java IO int port = 9000;ServerSocket ss = new ServerSocket(port);while (true) {final S...

zgw06629
2015/05/24
0
0
java NIO:IO与NIO的区别

一、概念 NIO即New IO,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。在Java API中提供了两套NIO,一套是针对标...

盼望明天
2018/09/11
0
0
Java NIO vs. IO

当学习了Java NIO和IO的API后,一个问题很快进入心中:我应该在何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地阐明Java NIO和IO的差异、它们的用例,以及它们如何影响您的代码设计。 ...

夕水溪下
2013/01/31
0
0
JAVA NIO编程入门(一)

JAVA NIO编程入门(一) 一、前言 笔者之前接触的NIO编程比较少,所以对这一块的基础也比较弱,NIO作为java编程中一个重要的模块,不能很好的掌握它,感觉自己在java方面就掌握的不够,所以,...

木木匠
2018/09/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【Python3之异常处理】

一、错误和异常 1.错误 代码运行前的语法或者逻辑错误 语法错误(这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正) def test: ^SyntaxError: invalid...

dragon_tech
15分钟前
0
0
编写可维护的 JavaScript

几乎每个程序员都有接手维护别人遗留项目的经历。或者,有可能一个老项目某一天又被重新启动。 通常情况下,接手老项目都会让人恨不得抛弃掉整个代码库从头开始。老代码凌乱、文档缺失、需要...

前端小攻略
27分钟前
0
0
Amino——框架层

框架层 目录 框架层... 1 Amino. 2 (一)、首页(TAB1)... 2 (二)、聊天(TAB2)... 3 (三)、我的社区(TAB3)... 5 (四)、探索(TAB4)... 6 (五)、钱包... 7 兴趣部落... 8 (一...

铸剑为犁413
44分钟前
0
0
k8s-dashboard

Kubernetes Dashboard 是一个管理Kubernetes集群的全功能Web界面,旨在以UI的方式完全替代命令行工具(kubectl 等) kubectl apply -f http://mirror.faasx.com/kubernetes/dashboard/master...

ZH-JSON
50分钟前
1
0
python如何安装库命令

python3 -m pip install 库名称

怪咖先生forever
51分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部