IO流与NIO块的数据缓存

  Java的IO是面向流设计的,通常我们通过IO流读取数据,只能指定读取数据的大小,而不能选择数据读取的起始位置。数据就像流水一样,流过我们的应用,一旦流过就无法回头。除非我们的代码对所读取的数据进行缓存,否则就再也见不到它了(针对此次流操作)。

  比如,我们创建一个byte[]数组来进行数据缓存,稍后可根据需要再次读取数组内的数据。但是有一点不方便的就是,如果我们要复用一个byte[]数组,即我们只处理了其中一部分数据,但是想用这个数组的剩余空间读入新数据。那我们就要在代码中维护一个偏移量offset,来告诉read操作,读取到的数据该从哪里开始存放。

  但是,如果使用NIO的ByteBuffer,就相对来说方便的多,它内部有维护几个字段,只要用户在对其进行读写后,正确地调用flip()方法,就可以复用缓冲对象。省去了维护偏移量的工作。

  而Netty,进一步完善了缓冲对象,它的ByteBuf对象,内部维护两个索引(读写)。也就不用再调用flip()方法了,降低错误概率。

注意:BufferedXXStream里面的缓冲数组没有发布,也就是说,它只在其内部使用,我们外部引用不到。它只是用来减少系统调用的。

IO与NIO的读写效率

  据说,在单线程场景下,IO的读写速度要高于NIO。(未考证)

   NIO的主要优点是,当读写条件不满足的时候,即缓冲区内没有数据,或没有空间的时候(这里的缓冲区指的应该是内核空间)。执行IO操作的线程不会被阻塞,所谓阻塞,指的是线程是否会被挂起。那么在多线程场景下,我们就可以利用这个优点,即在当读写条件满足的时候再执行IO操作。这样就省去了一定的等待时间,这段时间内,此线程可以做其他事情,如给另一个满足读写条件的Channel进行读写。

那我们如何知晓哪些Channel满足读写条件呢?

答案就是Selector,Seletor可以筛选注册在其上的Channel。可读,或可写的Channel将被筛选出来。

那如果有多个Channel同时满足读写条件呢?

那就把满足条件的Channel,每个都执行一遍。可读的就读,可写的就写。

那这样时效性会不会比较差?

是的,会比较差。拿网络IO来讲,如果一个线程处理多个连接的操作,那么最好情况就是,这几个连接,同时读写的概率不大,或者读写的数据量很小,线程处理速度很快,这样其他读写任务就不会等太久。但是,如果,这多个线程同时读写概率大,或者读写数据量大,处理速度较慢,而又比较追求时效性的话,那么一个线程最好不要处理太多连接。

有了NIO,BIO就被放弃了吗?

BIO就是阻塞IO,那网络IO来讲,如果此线程调用read()操作,且缓冲区无数据可读的时候,此线程将一直阻塞(被挂起),直到有数据可读,才被唤醒。前面说了,NIO的使用场景是,一个线程会维护多个连接,如果多个Channel同时满足条件,那么其中最后一个Channel就要等待它前面的Channel完成读写操作后,才能开始任务。如果此连接比较追求时效性的话,即要求,自己发送数据,对方能立即响应并进行处理的话。那么就可以用BIO进行处理,即用一个专门的线程来监听一个连接,甚至一个连接的读或写操作。

个人认为,BIO就像是高速公路上的专用车道,平时用的不多,但是需要的时候,可以立即使用,且不用跟其他车辆竞争。

【杂谈】对IO与NIO的认识的更多相关文章

  1. java的nio之:java的nio系列教程之java的io和nio的区别

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

  2. 面试题_66_to_75_Java IO 和 NIO 的面试题

    IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...

  3. 传统IO与NIO的比较

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

  4. Java IO 和 NIO

    昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...

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

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

  6. Nio学习4——EchoServer在IO,NIO,NIO.2中的实现

    堵塞IO实现: public class PlainEchoServer { public void serve(int port) throws IOException { final Server ...

  7. 理解IO、NIO、 AIO

    转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...

  8. Java NIO:IO与NIO的区别

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

  9. Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?

    IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...

随机推荐

  1. 摹客iDoc「标注」新玩法!这些细节让你爱不释手(201903-2版本更新)

    哈喽小伙伴们,我们又见面啦!没错,小摹就是来告诉大家:摹客iDoc又双叒叕升级了!这次又上线了许多新玩法,在此之前,小摹先带大家温习一下iDoc以往的知识点: 攻城狮查看标注的利器 —— 标注信息智能 ...

  2. SQL里执行CLR c#代码

    这里只说一个重点: 1.直接在sql里执行clr代码的时候,sql还是会报错 说没有启用 clr 执行以下代码才会起作用 EXEC sp_configure 'clr enabled', 1;  RE ...

  3. JS基础-分支结构-循环-数组

    1.分支结构  1.if结构    语法:    if(条件){       语句块:    }    注意:      1.条件尽量是boolean的,如果不是boolean的,以下条件值,会当做f ...

  4. (转)Flex 布局教程:

    这个博客的内容比较新,多看看 http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html [语法篇] http://www.ruanyifeng. ...

  5. 使用Linux自带日志滚动工具logrotate滚动redis日志示例

    截至到redis-5.0版本,redis仍然不会自动滚动日志文件,如果不处理则日志文件日积月累越来越大,最终将导致磁盘满告警: # ls -lh total 12G -rw-r--r-- 1 redi ...

  6. 使用pyenv在系统中安装多个版本的python

    pyenv的安装与使用 如果没有安装git,首先要安装git apt-get install git 安装完成后,使用自动安装程序提供的单行程进行安装: curl -L https://github. ...

  7. 如何将uniurlframe中html调用delphi的函数

    uniGUI总群中台中cmj朋友为我们总结了如下内容,对于利用delphi+uniGUI开发应用,可以说是精品,必须掌握. 一句话,如何在html与delphi间交互代码,是最好的答案. [Clien ...

  8. Spring之AOP由浅入深

    1.AOP的作用 在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加.AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可 ...

  9. Thinking in Java from Chapter 7

    From Thinking in Java 4th Edition final 1. 对于基本类型,final使数值恒定不变 2. 对于对象引用,final使引用恒定不变,即不能指向别的对象,但指向的 ...

  10. ES6-字符串扩展-padStart(),padEnd()

    ES6 引入了字符串补全长度的功能,如果某个字符串不够指定长度,会在头部活尾部补全. padStart() 用于头部补全: padEnd() 用于尾部补全. 上面代码中,padStart 和 padE ...