【杂谈】对IO与NIO的认识
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的认识的更多相关文章
- java的nio之:java的nio系列教程之java的io和nio的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- 面试题_66_to_75_Java IO 和 NIO 的面试题
IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...
- 传统IO与NIO的比较
本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...
- Java IO 和 NIO
昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
- Nio学习4——EchoServer在IO,NIO,NIO.2中的实现
堵塞IO实现: public class PlainEchoServer { public void serve(int port) throws IOException { final Server ...
- 理解IO、NIO、 AIO
转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...
- Java NIO:IO与NIO的区别
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?
IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...
随机推荐
- CentOS7 安装oracle客户端
1.本机环境CentOS7 64 [root@localhost etc]# uname -a Linux localhost.localdomain 3.10.0-693.el7.x86_64 #1 ...
- git 添加分支并与远程连接
今天由于项目需要,要改版,为了不影响当前网站,所以用分支来管理 首先,在本地添加分支dev git checkout -b dev 提交远程,让同事拉取这个分支,我是直接push了,推到远程. 同事在 ...
- MySQL优化(三) 表的设计
1.什么样的表才符合3范式(3 NF)? 表的范式,是首先符合1范式,才能满足2范式,进一步才能满足3范式:(现在最高级别是6范式) 第一范式:1NF 是对属性的原子性约束,要求表的属性(列)具有原子 ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- vue中的钩子函数的理解
接下来我们对几个钩子函数进行解释 beforeCreated:这个钩子函数实在vue实例创建后,触发的.这个时候还没有进行data里的数据监听和事件的初始化 其实大家很多时候都会在created钩子函 ...
- 【java】:Junit
创建单元测试文件 点击创建测试文件的目录,比如,我要在control目录下添加一个测试类,点击control文件夹 右键->new->other->junit test case 下 ...
- Java的 volatile关键字的底层实现原理
我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用.本文详细解读一下volat ...
- kbmmw 做REST 服务签名认证的一种方式
一般对外提供提供REST 服务,由于信息安全的问题, 都要采用签名认证,今天简单说一下在KBMMW 中如何 实现简单的签名服务? 整个签名服务,模仿阿里大鱼的认证方式,大家可以根据实际情况自己修改. ...
- delphi如何在form显示出来后处理指定的事件(例如自动登录)
最近写一个delphi客户端,遇到一个自动登录问题,已经解决了思路如下: 1.在Form的oncreate事件中读取用户配置文件,检查及处理是否保存了用户密码,是否自动登录,如果需要自动登录, 自动登 ...
- 2.第一个ASP.NET MVC 5.0应用程序
大家好,上一篇对ASP.NET MVC 有了一个基本的认识之后,这一篇,我们来看下怎么从头到尾创建一个ASP.NET MVC 应用程序吧.[PS:返回上一篇文章:1.开始学习ASP.NET MVC] ...