本文主要讲述下自己对IO的理解,对IO的用法和细则可能没有顾虑到。

本文的理解基于以下几篇文章,他们对各自部分都讲的很细,对我理解IO提供了很大帮助。

https://www.cnblogs.com/ylspace/p/8128112.html

该文主要讲解了Java IO的类体系以及他们各自的用处。

https://www.jianshu.com/p/03852a291c56

https://blog.csdn.net/fcbayernmunchen/article/details/8635427#commentBox

https://blog.csdn.net/cringkong/article/details/80274148

这些文章讲解了有关Java Buffer的原理,包括allocate、allocateDirect、map等不同IO方式他们的底层知识。

https://blog.yoodb.com/yoodb/article/detail/1498

该文章浅谈了NIO、AIO的知识。

正文

  首先是我整理的思维导图

IO的理解

  要理解Java IO设计得先了解系统IO,系统不允许程序直接访问硬盘,而是先将用户所需数据准备在系统缓冲区中再转移到用户内存,所以系统IO操作经过三个地方,1、硬盘 2、系统缓冲 3、用户进程空间。File就像是对硬盘的抽象,而stream/reader/writer就是对系统缓冲的抽象,而我们用的Buffer就是用户进程空间的抽象。

  IO的体系结构也是很直观的,对应字节处理和字符处理有了字节流inputstream、outputsream及字符流reader、writer。其中inputsream和reader对应输入流,outputsream、writer对应输出流。

根据接受或写出通道的不同,每个IO流类下衍生出了很多细分类用于处理不同通道。数据来源可以有如下:file、char[]、byte[]、网络流等。

装饰者模式

  在IO类中有一些类叫FilterXX及它的子类即是装饰者,比如我们常用的BufferInputSream和BufferOutStream,它可以自动帮我们建立并管理线程中的buffer。

  那么什么是装饰者模式呢?

  首先搞清楚装饰者的目的是:动态、透明地将责任附加到对象上,若要扩展功能,装饰者提供比继承更有弹性的替代方案。为了跟装饰前看起来一样,它和被装饰者共同装配了的同个接口,为了透明增加功能,它持有了被装配对象(其实是接口),它的方法包括了装饰功能和唤醒被装饰者的方法。

Why Decorator?

  装饰者的目的是对类进行拓展,这跟继承的目标相似。他们特点是什么呢?

l  动态性 装饰者对象可以在程序运行阶段根据需求动态的拓展功能,那个类需要拓展功能只要将相应装饰类组合进去。而继承则需要编译阶段就准备好所有可能性将各种组合可能性编译好进行选择。这会造成类冗杂。

l  解耦性 如果是集成需要层层继承,而上层类的功能改变势必会影响下级类的功能。装饰者则不会。

l  装饰者(和继承)可以在被装饰者的行为上扩展行为,也可以完全替代被装饰者的行为.

l  装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

l  当只能获取类对象没有class文件时只能用装饰者模式进行加强。

NIO的理解

  NIO是一种非阻塞式的IO,要理解它我们得先解决几个概念。

系统IO阶段: 1、数据准备阶段(系统从磁盘读取) 2、将系统缓冲数据转移到用户本地内存阶段。

什么是阻塞?非阻塞?

答:阻塞非阻塞注重的是数据准备阶段线程有没有造成线程等待,如果数据准备阶段线程需一直等待则是阻塞的,否则是非阻塞。

什么是同步?异步?

答:同步异步注重的是整个IO过程有没有造成IO等待,一些非阻塞IO虽然系统准备阶段没有造成等待,但将数据从内核缓冲区转移到用户内存里还是需要等待。

五种IO模型

由于篇幅有限,不重点讲IO模型,观点基于《UNIIX网络编程卷1:套接字联网API》 第六章。

同步阻塞IO:会造成整个IO过程等待。

同步非阻塞IO:系统准备数据阶段不会造成等待。

信号式IO:系统准备阶段不会造成等待,并且系统准备完成会发送信号给线程。

IO复用:由一个线程管理多个IO,底层调用时select和epoll(select需论询,epoll信号驱动),多个IO只要有一个准备好就线程就不会被阻塞,有效减少了系统准备阶段等待时间。

异步IO:整个IO无需等待。完成时返回成功指示。

  回到我们整体NIO,很明显NIO借用的是IO复用的思想。NIO常使用的三个类即是Selector、Buffer、Channel 。使用的方式就是将Channel注册到selector内,轮询到那个IO可用就在Channel和Buffer间进行读写信息。

  Selector有三种选择方法:select()、select(long timeout)、selectNow();前两种是阻塞式的,如果一个都没准备好还是会被阻塞,selectNow()是非阻塞式的,它能立即返回是否准备好的信号。

  同样继承AbstractSelectableChannel也可以通过设置configureBlocking(false)达到非阻塞的目的。我有一个疑问就是selectNow()+非阻塞Channel是否已经达到异步了呢?因为任何一个过程都没造成等待。当然具体以后再细究,因为Channel 是native代码。。。。

NIO中的Buffer分配方式,ByteBuffer.allocate()、ByteBuffer().allocateDirect()以及MappedByteBuffer、TransrferTo()

  普通IO方式是通过ByteBuffer.allocate(),在  Java堆上分配内存,因此系统IO过程是:硬盘→系统缓冲→用户内存空间→系统缓冲→硬盘。

  而ByteBuffer().allocateDirect()则是在native堆上分配内存,减少了native堆到Java堆中的复制,加快了速度,但也失去了Java GC的便利性。

  MappedByteBuffer:直接建立用户空间与硬盘间的映射,IO过程省略了数据复制到系统内核缓冲的步骤。这里有个问题是为什么需要系统内核缓冲?因为我们IO时往往会继续读取局部上下文,系统为了提高IO效率,直接在内核建立缓冲区缓冲IO数据的上下文以便接下来使用,但如果我们要IO大文件,文件大小超过系统缓冲,这样缓冲区显然是无意义的,因此有了这种方法来解决大文件的IO。

  TransferTO() 它是以上方法的包装,如果传递对象是FileChannel,则使用MappedByteBuffer的方式,如果是其他channel则使用allocateDirect()方式。

AIO

  AIO是完全的异步IO,它实现的核心是异步通道AsynchronizedXXChannel和获取异步结果的接口Future。

  异步通道进行读写时会另开一个线程进行IO操作,操作完成它会将改变接受结果类的完成信号并且将结果赋予到接收结果类(Future)上,我们需要结果时,通过访问接收类信号量,是则获取结果。

Java IO、NIO、AIO知识总结的更多相关文章

  1. 一文理解Java IO/NIO/AIO

      目录 概述 一.IO流(同步.阻塞) 二.NIO(同步.非阻塞) 三.NIO2(异步.非阻塞) 正文 概述 在我们学习Java的IO流之前,我们都要了解几个关键词 同步与异步(synchronou ...

  2. IO NIO AIO及常用框架概述

    概述 nio 同步: 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). 异步: 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需 ...

  3. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  4. java IO NIO BIO 最权威的总结

    1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 1.4 总结 2. NIO (New I/O) 2.1 NIO 简介 2.2 NIO的特性/N ...

  5. JAVA bio nio aio

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

  6. java BIO/NIO/AIO 学习

    一.了解Unix网络编程5种I/O模型 1.1.阻塞式I/O模型 阻塞I/O(blocking I/O)模型,进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误 ...

  7. Java IO/NIO教程

    Java IO教程 http://tutorials.jenkov.com/java-io/index.html Java NIO教程 英文版: http://tutorials.jenkov.com ...

  8. Java IO NIO详细讲解

    1.IO Java IO概述 2.NIO Java NIO浅析

  9. JAVA的 IO NIO AIO笔记

        IO      linux内核将所有外部设备都看做一个文件来操作,对一个文件的读写会调用内核系统命令,放回一个file descriptor(文件描述符), 对一个socket的读写也会有相应 ...

  10. Java之io nio aio 的区别

    这个问题最近面试总是遇到,作为一个只会写流水代码的程序员,一脸懵逼.看了网上的解释,看的还是很模糊,说下我对这个的理解. 先引出一个话题,两个大水缸,一个空一个满,让你把一个缸里面的水弄到另一个里面. ...

随机推荐

  1. 基于javaMail的邮件发送--excel作为附件

    基于JavaMail的Java邮件发送 Author xiuhong.chen@hand-china.com Desc 简单邮件发送 Date 2017/12/8 项目中需要根据物料资质的状况实时给用 ...

  2. mybatis的逆向工程和中文注解

    由于MyBatis Generator自带了生成注释的功能,但是,是英文的而且生成的根本无法理解,所以可以通过,修改他的源码来实现生成中文的注释,具体方式有以下几种: 1) 自定义CommentGen ...

  3. 指定的经纬度是否落在多边形内 java版

    这个想法算法就是判断一个点向左的射线跟一个多边形的交叉点有几个,如果结果为奇数的话那么说明这个点落在多边形中,反之则不在. A: B: C: D: E: no1: no2: y1: y2: 以上的AB ...

  4. Zuul转发请求时HttpHostConnectException can't cast to ZuulException问题解决方法

    看了一下github上的issue,这应该是一个bug.说是已经在zuul 2.0.1.RELEASE中处理了,但是我用的SpringBoot2.0.4.RELEASE中仍然有问题. 处理方案如下: ...

  5. Selenium之动作链(ActionChains)

    用selenium做自动化,有时候会遇到需要模拟鼠标操作才能进行的情况,比如单击.双击.点击鼠标右键.拖拽等等.而selenium给我们提供了一个类来处理这类事件——ActionChains   se ...

  6. python的日志配置

    settings.py中 DEBUG_TOOLBAR_CONFIG = { "JQUERY_URL": '//cdn.bootcss.com/jquery/2.2.4/jquery ...

  7. mysql 下的update select from的两种方式比较

    工作中遇到需要将一个表中的数据按照对应规则填入别的表中的情况 例如 表1 a a1    a2 11     90889 32     31241 12     52123 表2 b b1     b ...

  8. Python-Thread(通俗易懂)

    此类表示在单独的控制线程中运行的活动,有两种方法可以指定该活动,一是将可调用对象传递给构造函数,二是通过覆盖子类中的run()方法. 如果你对线程不太理解,我们可以打个比方,把线程数看作车辆数,我们来 ...

  9. 性能测试Jmeter压测ZooKeeper-自定义java请求

     要想通过自定义java请求来压测ZooKeeper,那么我们就需要做两件事情,第一我们需要知道java如何操作ZooKeeper,第二就是怎么能将我们写的jar包让jmeter识别,首先我们先来干第 ...

  10. C# 使用缓存数据模拟抢购

      在所有的电商网站中,不乏大量的抢购,比如双十一,双十二等等,作为一名开发人员考虑最多的就是多并发以及高并发 废话少说,开始写代码.我用了C#的MemoryCache代替试下流行的各种缓存 商品测试 ...