Java 中的 IO 和 NIO

Java IO

IO 面向字节流,是阻塞的。

  • Java IO 中读取数据和写入数据都是面向流(Stream),即当从流中读取、写入数据的同时也将数据写入流,流的含义在于没有缓存。如果需要获取某个数据的前一项或后一项数据,就必须主动地去缓存数据,无法直接从流中获取(面向流意味着当前只拥有一个数据流的切面),即只能顺序地从流中读取数据
  • Java IO 是阻塞的,当进行数据读写操作时,需调用的数据未准备好或当前不可写,读写操作就会阻塞直到数据准备完成或可写为止,即在这期间该线程无法做其他任何事情。
    • 阻塞 IO 会使线程将大量的时间浪费在等待 IO 上。但如果在数据可用时(满足请求条件)可用立即获取并处理数据,非阻塞 IO 则必须通过重复的调用来获取全部数据。

Java IO 工作流程

由于Java IO的阻塞性质,当面对多个流的读写时需要使用多个线程来处理。
如在网络 IO 中,Server 端使用一个线程监听一个端口,一旦某个连接被 accept,创建新的线程来处理新建立的连接。

在这里插入图片描述
read/write 是阻塞的

NIO

NIO 面向缓冲区,基于 Selector 的非阻塞。

  • Java NIO 中数据的读写是面向缓冲区(Buffer),读取时可以将整块的数据读取到缓冲区中,在写入时可将整个缓冲区的数据一起写入。面向流的数据读写只提供了一个数据流切面,而面向缓冲区的 IO 则使我们可以看到数据的上下文,即可以便利地在缓冲区中获取某项数据的前一项或后一项数据。 需要更好地管理缓冲区

    • 不能让新的数据覆盖缓冲区未处理的有用数据
    • 需要正确对缓冲区数据进行分块。分清已处理与未处理数据等
  • Java NIO 是非阻塞的,每一次数据读写调用都会立即返回,并将当前可读/可写的内容写入缓冲区,或从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作。

    • 例如,当 A 向 B 索取 100 块钱,B 只有60块,对于Java IO 来说会一直等待直到 B 凑够100块,对于 Java NIO 来说,不管 B 此时是否有足够的钱,都要马上返回结果,即 接收 B 当前拥有的 60 块,就算 B 没钱也要返回一个结果,绝不等待。
    • Java NIO 使用 Selector 实现单线程管理多个 Channel(通道),通过 select 调用,可获取已经准备好的 Channel 并进行相应的处理。

Java NIO 工作流程

Java NIO 提供 Selector 实现单个线程管理多个 channel 的功能。
在这里插入图片描述
Selectors

Java NIO的selectors允许一条线程去监控多个channels的输入,你可以向一个selector上注册多个channel,然后调用selector的select()方法判断是否有新的连接进来或者已经在selector上注册时channel是否有数据进入。selector的机制让一个线程管理多个channel变得简单。

select 调用可能是阻塞,也可能是非阻塞。
但 read/write 是非阻塞的。

总结:

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。

NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。

AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

  • NIO允许你用一个单独的线程或几个线程管理很多个channels(网络的或者文件的),代价是程序的处理和处理IO相比更加复杂。

  • 如果你需要同时管理成千上万的连接,但是每个连接只发送少量数据,例如一个聊天服务器,用NIO实现会更好一些,相似的,如果你需要保持很多个到其他电脑的连接,例如P2P网络,用一个单独的线程来管理所有出口连接是比较合适的。
    在这里插入图片描述

  • 如果你只有少量的连接但是每个连接都占有很高的带宽,同时发送很多数据,传统的IO会更适合
    在这里插入图片描述
    参考文章:https://blog.csdn.net/u010031673/article/details/51755075
    https://blog.csdn.net/linjpg/article/details/80962453

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值