• 什么是NIO(同步非阻塞)


    NIO的实现原理
    Java的NIO主要由三个核心部分组成:Channel、Buffer、Selector。

    基本上,所有的IO在NIO中都从一个Channel开始,数据可以从Channel读到Buffer中,也可以从Buffer写到Channel中。Channel有好几种类型,其中比较常用的有FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel等,这些通道涵盖了UDP和TCP网络IO以及文件IO。

    Buffer本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。Java NIO里关键的Buffer实现有CharBuffer、ByteBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。这些Buffer覆盖了你能通过IO发送的基本数据类型,即byte、short、int、long、float、double、char。

    Buffer对象包含三个重要的属性,分别是capacity、position、limit,其中position和limit的含义取决于Buffer处在读模式还是写模式。但不管Buffer处在什么模式,capacity的含义总是一样的。

    capacity:作为一个内存块,Buffer有个固定的最大值,就是capacity。Buffer只能写capacity个数据,一旦Buffer满了,需要将其清空才能继续写数据往里写数据。

    position:当写数据到Buffer中时,position表示当前的位置。初始的position值为0。当一个数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity–1。当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0。当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。

    limit:在写模式下,Buffer的limit表示最多能往Buffer里写多少数据,此时limit等于capacity。当切换Buffer到读模式时, limit表示你最多能读到多少数据,此时limit会被设置成写模式下的position值。

    三个属性之间的关系,如下图所示:
    在这里插入图片描述

    Selector允许单线程处理多个 Channel,如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件例如有新连接进来,数据接收等。

    这是在一个单线程中使用一个Selector处理3个Channel的图示:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/67a9ed8752214c57a3daf5e9d599c70e.png#pic_center在这里插入图片描述

    扩展阅读

    Java NIO根据操作系统不同, 针对NIO中的Selector有不同的实现:

    macosx:KQueueSelectorProvider

    solaris:DevPollSelectorProvider

    Linux:EPollSelectorProvider (Linux kernels >= 2.6)或PollSelectorProvider

    windows:WindowsSelectorProvider

    所以不需要特别指定,Oracle JDK会自动选择合适的Selector。如果想设置特定的Selector,可以设置属性,例如: -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider。

    JDK在Linux已经默认使用epoll方式,但是JDK的epoll采用的是水平触发,所以Netty自4.0.16起, Netty为Linux通过JNI的方式提供了native socket transport。Netty重新实现了epoll机制。

    采用边缘触发方式;

    netty epoll transport暴露了更多的nio没有的配置参数,如 TCP_CORK, SO_REUSEADDR等等;

    C代码,更少GC,更少synchronized

  • 相关阅读:
    wpf 异步等待框
    A tour of gRPC:01 - 基础理论
    AUTOSAR知识点 之 Det (一):Det内容浅分析(规范与实际使用均很少介绍,所以文章描述较模糊,读者研究规范比较好点)
    【校招VIP】java语言考点之switch和default
    堆的原理以及实现O(lgn)
    好朋友离职了,一周面试了20多场,我直呼内行
    2、从“键鼠套装”到“全键盘游戏化”审核
    m4a转换成mp3,音频格式轻松转换
    TF-IDF
    Python安装BeautifulSoup及使用方法,利用BeautifulSoup解析html网页
  • 原文地址:https://blog.csdn.net/ebdbbd/article/details/126324318