Buffer

1、缓冲区类型

2、缓冲区定义

(1)Buffer是一个对象,其中包含写入与读出的数据。是新IO与原IO的重要区别。任何情况下访问NIO中的数据都需要通过缓存区进行操作。
(2)Buffer在代码中体现就是一个数组,本质上就是内存中的一块区域。

Buffer源码

    public abstract class Buffer {
    // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

    // Used only by direct buffers
    // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
    long address;

    // Creates a new buffer with the given mark, position, limit, and capacity,
    // after checking invariants.
    //
    Buffer(int mark, int pos, int lim, int cap) {       // package-private
        if (cap < 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);
        this.capacity = cap;
        limit(lim);
        position(pos);
        if (mark >= 0) {
            if (mark > pos)
                throw new IllegalArgumentException("mark > position: ("
                                                   + mark + " > " + pos + ")");
            this.mark = mark;
        }
    }

    ...省略
}


(1)BUffer的四个属性。mark、position、limit、capacity。

  • [1] capacity:缓存区容量。设定即不可更改,比如 capacity 为 1024 的 IntBuffer,代表其一次可以存放 1024 个 int 类型的值。当Buffer 的容量达到 capacity,需要清空 Buffer,才能重新写入值。  
  • [2] limit:写模式是记录最大能够写入的数据。读模式下limit等于Buffer实际大小。  
  • [3] position:写模式下position初始值为0,当写入一个值时,position+1,指向下次写入位置。读模式下position会置0,这时将会从头开始读取Buffer中的数据。
  • [4] mark:Buffer#mark()记录当前position值,用于读写切换时还原position值。

(2)Netty提供了两个指针变量用于读写操作。分别是readerIndex与writeIndex。

  •  +-------------------+------------------+------------------+
    | discardable bytes |  readable bytes  |  writable bytes  |
    |                   |     (CONTENT)    |                  |
    +-------------------+------------------+------------------+
    |                   |                  |                  |
    0      <=      readerIndex   <=   writerIndex    <=    capacity
  • [1] readerIndex 到 writeIndex为可读度的字节缓存区。
  • [2] writeIndex 到 capacity为可写的字节缓存区
  • [3] 0 到 readerIndex为已读字节缓存区  

Channel

Channel定义

通道是数据来源与数据写入的目的地。主要分为以下几种,分别是FileChannel(文件通道,用于文件的读和写
)、DatagramChannel(用于 UDP 连接的接收和发送)、SocketChannel(把它理解为 TCP 连接通道,简单理解就是 TCP 客户端)、ServerSocketChannel(TCP 对应的服务端,用于监听某个端口进来的请求)

NIO Channel与Java stream区别

  • 对于同一个 Channel全双工,Stream(InputStream、OutputStream)要么读要么写
  • Channel 可以非阻塞的读写 IO 操作,而 Stream 只能阻塞的读写 IO 操作。
  • Channel 必须配合 Buffer 使用,总是先读取到一个 Buffer 中,又或者是向一个 Buffer 写入。也就是说,我们无法绕过 Buffer ,直接向 Channel 写入数据。

为什么Netty重写Channel?

  • [1]Channel是Netty的核心,为了能够与整体架构融合在一起。(待确定)

参考

[1] http://ifeve.com/java-nio-all/


多路复用器Selector

Selector会不断轮询注册在其上的Channel,当某个Channel上发生事件,该Channel就处于就绪状态,会被轮询出来进行后续IO操作。

通过一个线程(多路复用器)Selector可以同时轮询多个Channel,不必一个连接一个线程以一对一的形式应对请求,极大地减少系统开销。


当读或写事件发生时,就会从Selector中获取想用的SelectorKey,SelectionKey中可以找到发生的事件和该事件所发生的具体的SelectableChannel,以获得客户端发送过来的数据.

NIO服务端

003——Netty之Buffer、Channel以及多路复用器Selector的更多相关文章

  1. NIO的Buffer&Channel&Selector

    java的NIO和AIO Buffer position.limit.capacity 初始化 Buffer 填充 Buffer 提取 Buffer 中的值 mark() & reset() ...

  2. Netty那点事: 概述, Netty中的buffer, Channel与Pipeline

    Netty那点事(一)概述 Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户ne ...

  3. Netty服务端Channel注册Selector及绑定服务器端口

    当服务端Channel 创建并且初始化完成之后,会将其注册到 selector,通过语句config().group().register(channel)进行注册工作,该方法最终调用 Abstrac ...

  4. Java NIO系列教程(六) 多路复用器Selector

    多路复用器Selector是Java NIO编程的基础,熟练地掌握Selector对于掌握NIO编程至关重要.多路复用器提供选择已经就绪的任务的能力.简单来讲,Selector会不断地轮询注册在其上的 ...

  5. netty中的Channel、ChannelPipeline

    一.Channel与ChannelPipeline关系 每一个新创建的 Channel 都将会被分配一个新的 ChannelPipeline.这项关联是永久性 的:Channel 既不能附加另外一个 ...

  6. Netty 源码 Channel(二)核心类

    Netty 源码 Channel(二)核心类 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel 类图 二. ...

  7. Netty 源码 Channel(二)主要类

    Netty 源码 Channel(二)主要类 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Channel 类图 二. ...

  8. Netty 源码 Channel(一)概述

    Netty 源码 Channel(一)概述 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Channel 为 Netty ...

  9. Netty服务端Channel的创建与初始化

    Netty创建服务端Channel时,从服务端 ServerBootstrap 类的 bind 方法进入,下图是创建服务端Channel的函数调用链.在后续代码中通过反射的方式创建服务端Channel ...

随机推荐

  1. 第八章 Fisco Bcos 国密版本的部署、控制台搭建、合约的部署、sdk 调用

    鉴于笔者以前各大博客教程都有很多人提问,早期建立一个技术交流群,里面技术体系可能比较杂,想了解相关区块链开发,技术提问,请加QQ群:538327407 参考资料 证书说明:https://mp.wei ...

  2. redis快速部署

    1. 场景描述 以前是直接使用公司提供的redis集群,只使用不负责维护,因项目用到负载均衡,需要使用redis做session共享,存储session信息,所以就部署了下,记录下以便后续能快速部署. ...

  3. 各类最短路算法基本模板-C++

    原文转自:https://blog.csdn.net/changjiale110/article/details/77394650 感谢. #define Max 0x3f3f3f3f #define ...

  4. 批量替换git目录的远程仓库URL地址脚本

    需求: 1. 输入work-dir 工作目录 2. 扫描工作目录中的子目录 3. 对每一个子目录, 判断是否是git repo 4. 确认是git repo, 获取git origin remote- ...

  5. Lucene04-Lucene的基本使用

    Lucene04-Lucene的基本使用 导入的包 import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.ap ...

  6. Devops-运维效率之数据迁移自动化

    overmind系统上线三个月,累计执行任务800+,自动审核执行SQL超过5000条,效率提升相当明显,离"一杯咖啡,轻松运维"的目标又进了一步. 写在前边 overmind系统 ...

  7. 洛谷P3275 [SCOI2011]糖果 题解

    题目链接: https://www.luogu.org/problemnew/show/P3275 分析: 本题就是一个裸的差分约束. 核心: x=1x=1x=1时,a=b,a−>b,b−> ...

  8. [leetcode] #112 Path Sum (easy)

    原题链接 题意: 给定一个值,求出从树顶到某个叶(没有子节点)有没有一条路径等于该值. 思路: DFS Runtime: 4 ms, faster than 100.00% of C++ class ...

  9. JavaScript数组高性能去重解决方案

    在大多数的人眼里,数组去重是一个很简单的课题,很多人甚至熟练掌握了多种数组去重的方法,然而大多时候,我们却忽略了数组去重所消耗的时间资源.譬如我们在做前端性能优化的时候,又有多少人会考虑JavaScr ...

  10. Java中返回值定义为int类型的 方法return 1返回的是int还是Integer&&finally中return问题

    在Java中返回值定义为int类型的 方法return 1:中返回的是Integer值,在返回的时候基本类型值1被封装为Integer类型. 定义一个Test类,在异常处理try中和finally中分 ...