Java NIO(New Input/Output)——新的输入/输出API包——是2002年引入到J2SE 1.4里的。Java NIO的目标是提高Java平台上的I/O密集型任务的性能。

简单描述NIO与IO不同点:

IO NIO
面向流 面向缓冲
阻塞IO 非阻塞IO
选择器(selector)

面向流与面向缓冲 
Java NIO与IO的最大区别就是,IO是面向流的,NIO是面向缓冲的。

  • 面向流:java IO面向流指的是每次都是从流中读取一个或多个字节,直到读取完所有字节,期间并没有被缓存,如需缓存需要另加到缓存区(如通过BufferedInputStream)。
  • 面向缓冲:Java NIO面向缓冲指的是数据直接被读取到稍后处理的缓冲区中,需要的时候在从缓冲区获取数据。这就增加了处理的灵活性,但是读取数据的时候需要检查缓冲区是否含有所需要的数据。

阻塞IO与非阻塞IO

  • 阻塞IO: java IO中各种流是阻塞的,意思是当线程执行read()或write()操作时,该线程不能干其他事情,直至读,写操作完成。所以这种模式一旦有大规模的并发行为时,每一个访问都需要开启一个单独的线程进行处理,这样就会有大量的线程切换操作,影响效率。
  • 非阻塞IO: Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作。所以一个单独的线程现在可以管理多个输入和输出通道(channel),只要注册到一个selector中,当有数据放入通道的时候,selector就会得知哪些channel就绪,这时就可以做响应的处理,这样服务端只有一个线程就可以处理大部分情况(当然有些持续性操作,比如上传下载一个大文件,用NIO的方式不会比IO好)。

通过两个模式的比较,可以看出IO是直连的,每个请求都给一条线程来处理,但是NIO却是基于选择器(selector)来处理,直到读写的数据准备好后,才会通知相应的线程来进行处理。总而言之:“selector不会让channel白占资源,没事的时候给我去睡觉。”

注意:NIO是基于字节进行传输,在IO时要注意decode/encode。

通道(Channel) 
java.io类中没有一个类能够读写Buffer类型,所以NIO中提供了Channel类来读写Buffer。通道可以认为是一种连接,可以是到特定设备,程序或者是网络的连接。类似于IO的stream,但是不同的是除了FileChannel,其他的channel都能以非阻塞状态运行。FileChannel执行的是文件的操作,可以直接DMA操作内存而不依赖于CPU。其他比如SocketChannel就可以在数据准备好时才进行调用。

选择器(Selector) 
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

字符编码 
向ByteBuffer中存放数据涉及到两个问题:字节的顺序和字符转换。ByteBuffer内部通过ByteOrder类处理了字节顺序问题,但是并没有处理字符转换。事实上,ByteBuffer没有提供方法读写String。所以通过Java.nio.charset.Charset处理了字符转换问题。

Java之NIO与IO比较分析的更多相关文章

  1. 二十四、JAVA的NIO和IO的区别

    一.JAVA的NIO和IO 1.NIO:面向缓冲区(buffer)(分为非阻塞模式IO和阻塞模式IO)组成部分:Channels管道,Buffers缓冲区,Selectors选择器 2.IO:面向流( ...

  2. Java中 NIO与IO的区别

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

  3. java 的nio与io对比

    转:本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提 ...

  4. Java中NIO和IO区别和适用场景

    NIO是为了弥补IO操作的不足而诞生的,NIO的一些新特性有:非阻塞I/O,选择器,缓冲以及管道.管道(Channel),缓冲(Buffer) ,选择器( Selector)是其主要特征. 概念解释: ...

  5. Java NIO 和 IO 的区别详解

    Java NIO为jdk1.4提供了新的API,本文主要来比较一下Java中NIO和IO的区别,Java初学者可以了解一下. 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分 ...

  6. Java中的NIO和IO的对比分析

    总的来说,java中的IO和NIO主要有三点区别: IO NIO 面向流 面向缓冲 阻塞IO 非阻塞IO 无 选择器(Selectors) 1.面向流与面向缓冲 Java NIO和IO之间第一个最大的 ...

  7. JAVA中IO和NIO的详解分析,内容来自网络和自己总结

    用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...

  8. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  9. Java NIO与IO的区别和比较

    传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...

随机推荐

  1. Object#wait()与Object#wait(long)的区别

    例子 例1 最基础的等待-通知 下面一个例子,一个线程"waiting"在同步代码块调用了Object#wait()方法,另一个线程"timedWaiting" ...

  2. MySQL 删除表中所有数据

    方法一:使用 delete from [表名]    生成日志 方法二:使用 truncate table [表名]    无日志生成 两种方式删除后再插入数据,第一条id的值不一样 方法一: 方法二 ...

  3. Python os.remove() 方法

    概述 os.remove() 方法用于删除指定路径的文件.如果指定的路径是一个目录,将抛出OSError.高佣联盟 www.cgewang.com 在Unix, Windows中有效 语法 remov ...

  4. PDOStatement::errorCode

    PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE(PHP 5 >= 5.1.0, PECL pdo >= 0.1.0) 说明 语法 st ...

  5. 7.11 NOI模拟赛 qiqi20021026的T1 四个指针莫队 trie树

    LINK:qiqi20021026的T1 考场上只拿到了50分的\(nq\)暴力. 考虑一个区间和一个区间配对怎么做 二分图最大带权匹配复杂度太高. 先考虑LCS的问题 常见解决方法是后缀数组/tri ...

  6. dfs树

    dfs树是解决图中带环的利器. 前天CF的F题就是dfs树,但是当时我没有认真思考 觉着找到一个环过于困难 当时没有想到 也没理解dfs树的意义. 对于一张无向图求出一个dfs树 这个树有两种边 树边 ...

  7. 重学c#系列——异常(六)

    前言 用户觉得异常是不好的,认为出现异常是写的人的问题. 这是不全面,错误的出现并不总是编写程序的人的原因,有时会因为应用程序的最终用户引发的动作或运行代码的环境而发生错误,比如你用android4去 ...

  8. C++中unordered_map几种按键查询比较

    unorder_map有3种常见按键查值方法. 使用头文件<unordered_map>和<iostream>,以及命名空间std. 第一种是按键访问.如果键存在,则返回键对应 ...

  9. Pytest单元测试框架-allure测试报告

    Allure Test Report 对于不同的编程语言,有很多很酷的测试框架.不幸的是,它们中只有少数能够提供测试执行输出的良好表示.Qameta软件测试团队正在致力于Allure--一个开源框架, ...

  10. 44-final, finally, finalize的区别

    final—修饰符(关键字) 如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承. 因此一个类不能既被声明为 abstract的,又被声明为final的.将变量或方法声明为 ...