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. Linux安装httpd

    一.相关下载 1.httpd下载 官网下载:http://httpd.apache.org/ 或者 百度网盘链接: https://pan.baidu.com/s/1JPdU28tv6rePKJanB ...

  2. spring系列(一):超级经典入门

    一  spring是什么 Spring是一个开源框架,它由RodJohnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情. ...

  3. mysql数据库建表分类字段--尽量少用字符串--原因探索

    虽然一直都知道,类型 之类的字段 直接用字符窜会很方便,不过最好还是不要用字符串:但是也不是特别清楚为什么不要用,时间久了 就忍不住用一下字符窜试试,这一试 还挺好用的,吓得我 感觉探究了一下 为什么 ...

  4. 调用另一个进程,createprocess返回值正确,但被调进程连入口函数都没进入。

    1.单独运行被调进程(提示atl不匹配). 2.编译选项设置为不依赖atl即可. 3.启发:能单独测试的,先单独测试.

  5. UVA514 铁轨 Rails:题解

    题目链接:https://www.luogu.org/problemnew/show/UVA514 分析: 入站序列是1-n,入站后判断如果等于出站序列的当前值,则直接出站.否则就在栈里待着不动.模拟 ...

  6. java多线程总结-同步容器与并发容器的对比与介绍

    1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ...

  7. 一些学习js的算法题目

    1.排序 问题描述 编写一个程序,输入3个整数,然后程序将对这三个整数按照从大到小进行排列. 输入格式:输入只有一行,即三个整数,中间用空格隔开. 输出格式:输出只有一行,即排序后的结果. 输入输出样 ...

  8. 小代学Spring Boot之自定义Starter

    想要获取更多文章可以访问我的博客 - 代码无止境. 上一篇小代同学在Spring Boot项目中配置了数据源,但是通常来讲我们访问数据库都会通过一个ORM框架,很少会直接使用JDBC来执行数据库操作的 ...

  9. python课堂整理13---函数的作用域及匿名函数

    name = 'alex' def foo(): name = 'jinling' def bar(): print(name) return bar a = foo() print(a) 阅读上述代 ...

  10. 在pom.xml中的dependencies点击add怎么没有搜索到相关jar包

    1.eclipse菜单 window-> show view –> other –> Maven 2.在打开的窗口里,右键 local repositories –> loca ...