Java IO/NIO

9 篇文章 0 订阅

Java IO/NIO

概念:阻塞与非阻塞
阻塞与非阻塞是描述进程在访问某个资源时,数据是否准备就绪的的一种处理方式。当数据没有准备就绪时:

  • 阻塞:线程持续等待资源中数据准备完成,直到返回响应结果。
  • 非阻塞:线程直接返回结果,不会持续等待资源准备数据结束后才响应结果。

概念:同步与异步

  • 同步与异步是指访问数据的机制,同步一般指主动请求并等待IO操作完成的方式。
  • 异步则指主动请求数据后便可以继续处理其它任务,随后等待IO操作完毕的通知。

概念:BIO、AIO、NIO

  • BIO:同步阻塞(blocking-IO)
  • NIO:同步非阻塞(non-blocking-IO)
  • AIO:异步非阻塞(synchronous-non-blocking-IO)

小结:

  • 同步:你观察他(进程观察数据)
  • 异步:他通知你(数据ok通知进程)
  • 阻塞:等着
  • 非阻塞:不等

阻塞 & 非阻塞

  • 阻塞:读写数据过程中,内核查看数据是否就绪,没有就绪则线程阻塞状态交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除 block 状态。data = socket.read() //数据未就绪一直阻塞在read方法
  • 非阻塞:线程从某通道进行读写数据,没数据可用该线程执行其他任务。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以单独的线程可以管理多个输入和输出通道。

NIO(New IO / Non Blocking IO)

NIO重点是Channel(通道),Buffer(缓冲区),Selector(选择器)。⽀持⾯向缓冲的,基于通道的 I/O 操作⽅法。代替原来的Java IO API。

传统IONIO
面向流(数据流动)面向缓冲区Buffer(通道Channel用于传输,没有数据)
单向(输入、输出流)双向
阻塞非阻塞
选择器

后两个针对网络

Buffer

在Java NIO中负责数据的存取,缓冲区就是数组,用于存储不同数据类型的数据。根据数据类型不同(除了boolean),提供了相应类型的缓冲区。eg:LongBuffer、CharBuffer……。
通过allocate()获取缓冲区。

缓冲区存取数据的核心方法:
put() //存入数据到缓冲区
get() //获取缓冲区中的数据
缓冲区中的四个核心属性
private int mark = -1; //标记,表示记录当前position的位置。通过reset()恢复到mark的位置
private int position = 0;  //位置,缓冲区中正在操作数据的位置
private int limit; //界限,缓冲区中可以操作数据的大小(limit后数据不能进行读写)。
private int capacity; //容量,缓冲区中最大存储数据的容量,一旦声明不能改变。
0 <= mark <= position <= limit <= capacity
直接缓冲区和非直接缓冲区
  • 非直接缓冲区:通过allocate()方法分配缓冲区,将缓冲区建立在JVM内存中。
  • 直接缓冲区:通过allocateDirect()方法分配直接缓冲区,将缓冲区建立在物理内存中(gc回收不到)。可以提高效率。不安全、消耗资源大、不易控制。

在这里插入图片描述
在这里插入图片描述
中间copy方法重复,所以在NIO中建立内存映射文件(直接缓冲区),在OS中的物理内存中建立缓冲区。
在这里插入图片描述

Channel

java.nio.channels包定义。Channel表示IO源与目标打开的连接。Channel本身不能直接访问数据,只能与Buffer交互。用于源节点与目标节点的连接。在Java NIO中负责缓冲区中的数据传输。Channel本身不存储数据,需要配合缓冲区进行传输。

主要实现类

java.nio.channels.Channel接口

  • FileChannel
  • 网络IO TCP
    • SocketChannel
    • ServerSocketChannel
  • 网络IO UDP
    • DatagramChannel
获取通道
  1. 支持通道的类实现getChannel()方法
    本地IO:
    FileInputSteam / FileOutputSteam RandomAccessFile
    网络IO:
    Socket ServerSocket
  2. JDK1.7中NIO.2针对各个通道提供了静态方法open()
  3. JDK1.7中NIO.2的Files工具类的newByteChannel()方法
    直接缓冲区只有byteBuffer支持
通道之间数据传输

transformFrom():outChannel.transferFrom(inChannel,0,inChannel.size());
transformTo():inChannel.transferTo(0,inChannel.size(),outChannel);

分散(Scatter)与聚集(Gather)
  • 分散读取(Scattering Reads):将通道中的数据分散到多个缓冲区中
  • 聚集写入(Gathering Writes):将多个缓冲区中的数据聚集到一个通道中

在这里插入图片描述

字符集(CharSet)
  • 编码:字符串→字节数组 encode()
  • 解码:字节数组→字符串decode()

Selector(选择器)

NIO非阻塞模式,把每个通道都注册到该选择器上,选择器监控这些通道的状况。当某个通道上的某个请求事件完全准备就绪,选择器分配至服务端一个或多个线程上。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
摘自:尚硅谷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值