• NIO基础


    nio :  non-blocking io 非阻塞IO

    1. 三大组件

    1.1 channel和buffer

    channel 有点像stream ,他就是读写数据的双向通道,可以从channel将数据读入buffer,也可以将buffer的数据写入channel,之前的stream 要么输入,要么输出;channel 比stream更加底层  。

    常见的channel
    1. FileChannel:用于文件的读取和写入操作。可以从文件中读取数据到缓冲区,也可以将数据从缓冲区写入文件。

    2. SocketChannel:用于通过TCP协议进行网络通信。可以连接到远程服务器并发送和接收数据。

    3. ServerSocketChannel:用于监听TCP连接请求。可以接受来自客户端的连接请求,并创建对应的SocketChannel进行通信。

    4. DatagramChannel:用于通过UDP协议进行网络通信。可以发送和接收UDP数据包。

    这些Channel的功能主要包括:

    • 读取数据:可以从Channel中读取数据到缓冲区,供后续处理使用。

    • 写入数据:可以将数据从缓冲区写入到Channel中,发送给对应的目标。

    • 非阻塞模式:可以将Channel设置为非阻塞模式,以便在没有数据可读或可写时立即返回,而不是一直等待。

    • 文件操作:FileChannel可以进行文件的读取和写入操作,包括读取文件内容、写入文件内容、文件的位置操作等。

    • 网络通信:SocketChannel和ServerSocketChannel可以进行网络通信,包括连接远程服务器、发送和接收数据等。

    这些Channel提供了更高级别的IO操作,相比于传统的InputStream和OutputStream,更加灵活和高效。通过使用这些Channel,可以实现更好的IO性能和更多的IO操作控制。

            buffer 不多多赘述

    Buffer对象具有以下几个重要的属性和方法:

    • 容量(Capacity):表示Buffer的最大容量,即它可以存储的最大数据量。

    • 位置(Position):表示当前读写的位置,初始位置为0。

    • 限制(Limit):表示有效数据的末尾位置,初始限制为容量。

    • 标记(Mark):用于临时存储位置的标记,可以通过调用mark()方法设置标记,通过调用reset()方法恢复到标记位置。

    • 读写操作:可以通过put()方法将数据写入Buffer,通过get()方法从Buffer中读取数据。

    • 翻转(Flip):将Buffer从写模式切换到读模式,即将限制设置为当前位置,位置设置为0。

    • 清空(Clear):将Buffer从读模式切换到写模式,即将位置和限制都设置为容量。

    • 压缩(Compact):将未读取的数据复制到Buffer的起始位置,然后将位置设置为未读取数据的末尾。

    Buffer提供了一种方便的方式来处理数据,可以通过读写操作来操作Buffer中的数据,并且可以通过翻转、清空等方法来控制读写的位置和限制。在NIO中,Buffer与Channel配合使用,可以实现高效的数据读写操作。

    Selector

    selector但从字面意思上不好理解,接下来需要结合服务器的设计演化来理解它的用途

    多线程版设计

            缺点:连接数一多就不行了,大量数据来了,就会创建大量thread,到一定程度会造成oom。

    而且线程上下文切换开销也会增大。因为你这个多线程我这个几个cpu吃不住。

    线程池版设计

              虽然避免了oom ,降低了上下文切换的开销。但是他是在阻塞模式下工作的,就好比你的线程池里的一个线程,只能等待服务完一个socket之后才能服务完另一个socket。所以他只适合短链接的场景。

    selector版的设计

    selector 的作用就是配合一个线程来管理多个channel,获取这些channel 上发生的事件,这些 channel 工作在非阻塞模式下,不会让线程吊死在一个 channel 上。适合连接数特别多,但流暴低的场景 (low traffic)

    调用selector 的select0 会阻塞直到channel 发生了读亏就緒事件,这些事件发生,select 方法就会返回这些事件交给 thread 来处理

    讲个小案例就是说 selector好比服务员 ,channel 好比客人。channelA把服务员selector说了我来一份饺子 ,又说我在想想,与此同时channelB说我来个包子,这时候selector不会等着A,而是转头给B一个包子。但是a是个吃货我要这个还要哪个等等 这时候channel会一直服务a,但如果a说我在想想还要啥,selector就去服务其他客人了。  这就是非阻塞的去处理事件

  • 相关阅读:
    Node.js安装及环境配置
    React项目实战之租房app项目(六)渲染房源列表&axios优化&封装顶部搜索栏&列表找房模块之条件筛选
    Jetson Orin 平台单进程采集四路独立video调试记录
    Python编程基础:实验6——函数的递归
    Part03-DatabaseStorage i
    go语法基础二(结构体,协程,锁,xml,io)
    ADOP告诉您光分路器的类型?如何选择?
    【带头学C++】----- 七、链表 ---- 7.5 学生管理系统(链表--上)
    HTML+CSS大作业:基于HMTL校园学校网页设计题材【我的学校网站】
    Going Deeper With Convolution(GoogLeNet的理解)
  • 原文地址:https://blog.csdn.net/qq_52988841/article/details/133362070