JAVA IO&NIO

多路复用IO模型

多路复用 IO 模型就像是一个忙碌的调度员,它负责监控多个通道(比如电话线),只有当通道真正有消息传来时,调度员才会通知相应的工作人员去处理。这样就可以节省资源,因为不需要每个通道都有一个专门的工作人员等待消息。

在这个模型中,socket指的是网络通信中的一个端点,可以理解为一台计算机上的一个通信端口。当两台计算机通过网络通信时,它们会建立一个socket连接,通过这个连接可以进行数据的传输。

多路复用 IO 模型通过一个线程来管理多个socket连接,只有当有数据传输时,才会真正调用IO操作。这样可以减少资源的占用,并提高效率。但是需要注意的是,如果事件响应体很大,可能会导致后续事件得不到及时处理。

信号驱动 IO 模型

在信号驱动 IO 模型中,当用户线程发起一个 IO 请求操作,会给对应的 socket 注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时会发送一个信号给用户线程,用户线程接收到信号之后,便在信号函数中调用 IO 读写操作来进行实际的 IO 请求操作。

异步IO模型

异步IO模型就像是一个快递员,当用户下单后,快递员就会立刻去处理其他订单,而不需要等待这个订单处理完毕。当快递员收到一个订单后,他会立刻确认订单已经接收,并开始准备派送货物。当货物准备好后,他会通知用户订单已经完成,不需要用户再次确认或者等待。

在异步IO模型中,用户线程发起IO操作后就可以继续做其他事情,不会被IO操作阻塞。内核会负责处理IO操作的整个过程,并在完成后通知用户线程。用户线程不需要关心IO操作的具体细节,只需等待操作完成的通知即可。

异步IO的优势在于可以提高系统的并发性能,因为用户线程不会被IO操作阻塞,可以更有效地利用系统资源。同时,异步IO模型也减少了用户线程与内核之间的交互次数,提高了系统的效率。

NIO

NIO 主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统 IO 基于字节流和字 符流进行操作,而 NIO 基于 Channel 和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区 中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开, 数据到达)。因此,单个线程可以监听多个数据通道。
在NIO中,单个线程可以监听多个数据通道是通过Selector来实现的。Selector是一个可以监听多个Channel事件的对象,它会不断轮询注册在其上的Channel,当有事件发生时,会通知对应的Channel。

具体过程如下:

  1. 创建一个Selector对象,并将多个Channel注册到这个Selector上。
  2. 当调用Selector的select()方法时,Selector会阻塞直到有Channel发生事件。
  3. 当有事件发生时,Selector会返回一个就绪的SelectionKey集合,表示有事件发生的Channel。
  4. 遍历就绪的SelectionKey集合,根据具体事件类型进行处理,比如读取数据、写入数据等操作。
  5. 处理完事件后,可以继续调用select()方法等待下一次事件发生。

通过这种方式,一个单独的线程就可以有效地管理多个Channel的事件,提高了系统的并发性能和效率。同时,Selector的使用也避免了创建多个线程来处理每个Channel的事件,减少了线程之间的切换和资源消耗。
NIO 和传统 IO 之间第一个最大的区别是,IO 是面向流的,NIO 是面向缓冲区的。

区别

NIO(New Input/Output)和传统的IO在处理IO操作时有一些区别:

  1. 面向流 vs 缓冲导向:

    • 传统的IO是面向流的,每次从流中读取或写入一个字节或字符,数据不会被缓存。而NIO是缓冲导向的,数据会先读取到缓冲区中,可以在缓冲区中前后移动数据,增加了处理数据的灵活性。
  2. 阻塞IO vs 非阻塞IO:

    • 传统的IO是阻塞IO,即在IO操作期间会阻塞程序的执行,直至数据准备就绪。而NIO是非阻塞IO,通过Selector可以实现单线程管理多个通道,当某个通道有数据准备好时,可以立即处理,不会阻塞程序的执行。
  3. 同步IO vs 异步IO:

    • 传统的IO是同步IO,即程序请求IO操作后需要等待IO操作完成才能继续执行后续操作。而NIO是异步IO,程序请求IO操作后可以立即继续执行后续操作,当IO操作完成后会通过信号通知程序。
  4. 多路复用IO:

    • NIO通过Selector实现了多路复用IO,可以在单个线程中管理多个通道,提高了系统的并发性能和效率。传统的IO通常需要为每个连接创建一个线程,如果连接较多会导致线程资源的浪费。

总的来说,NIO相比传统的IO具有更高的效率和灵活性,尤其适用于处理大量连接和数据的高并发情况。通过NIO可以更好地利用系统资源,提高系统的性能和响应速度。

通道,缓冲区,监测器

在NIO中,Channel就像是一条双向的通道,可以用来进行数据的读取和写入操作,类似于一条水道。与传统的单向流不同,Channel可以在读取数据的同时也可以写入数据,提供了更多的灵活性。

  • NIO 中的 Channel 的主要实现有:
    1. FileChannel
    2. DatagramChannel
    3. SocketChannel
    4. ServerSocketChannel
      Buffer就像是一个容器,类似于一个水桶,是一个连续数组,用来存放数据。在NIO中,数据的读取或写入都需要经过Buffer,就好像水必须先被装进水桶中才能进行传输。数据从Channel读取到Buffer中,或者从Buffer写入到Channel中,实现了数据在通道间的传输。
  • 在 NIO 中,Buffer 是一个顶层父类,它是一个抽象类,常用的 Buffer 的子类有:ByteBuffer、IntBuffer、 CharBuffer、 LongBuffer、 DoubleBuffer、FloatBuffer、ShortBuffer

Selector则像是一个多功能的调度员,能够同时监控多个通道上是否有事件发生。当有事件发生时,Selector会负责获取事件并进行相应的处理。这样就可以通过一个单线程管理多个通道,避免了为每个连接创建一个线程的开销。只有在通道真正有读写事件发生时,才会调用相应的函数进行处理,大大减少了系统资源的消耗。

综合起来,NIO的Channel、Buffer和Selector就像是水道、水桶和调度员的组合,实现了高效的数据传输和管理,提高了系统的并发性能和效率。通过这些机制,可以更好地处理大量连接和数据的高并发情况,提升系统的性能和响应速度。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇