NIO 三大核心 Buffer(缓冲区)、Channel(管道)、Selector(选择器)

   对于如今的数据时代,响应速度不仅取决于服务器的硬件,对于服务的设计实现更是重中之重。所以对资源的利用率便城市代码实现的一大考量点。这就更加体现出的NIO在实际开发中的重要性。随着框架的封装度日益提高,人们更加注重与对它的实际使用,但是对于底层的了解才是处理解决生产问题的正确路径。

NIO的核心分为三块

  • Channel(通道)
  • Buffer(缓冲区)
  • Selector(选择器)

(1)Channel

      它是从节点获取数据的工具,与Stream流有类似之处。但是流是单向流通的,而通道是双向的。

      通道的类别也有很多

  • FileChannel 文件管道的数据
  • Pipe.SourceChannel 线程间通信的管道
  • SocketChannel 用于TCP网络通信的管道
  • DatagramChannel 用于UDP网络通信的管道

     这是比较来说常用的几种。

(2)Buffer

    缓冲区则是数据在通道传输的载体。

   底层是数组结构,可以进行get/set操作 Buffer没有构造器,使用时通过XxxBuffer.allocate(int n)方法进行分配,创建容量为n的对象

Buffer底层示意图

有三个比较重要的属性capacity (容量)  limit (界限) position (位置)。

初始化时,position=0,limit=capacity 调用put方法存入数据,positon向后移动,代表数据处理的位置 装载数据完成后,调用flip,切换读写模式,操作索引的方法 读出数据完成后,调用clear,清空初始位置的方法。

用代码片段认识Buffer属性


        ByteBuffer buffer = ByteBuffer.allocate(8);
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("limit:" + buffer.limit());
        System.out.println("position:" + buffer.position());

        buffer.put("yu".getBytes());
        System.out.println("=========存入y&u");
        System.out.println("position:" + buffer.position());


        buffer.flip();
        System.out.println("=========调用flip");
        System.out.println("limit:" + buffer.limit());
        System.out.println("position:" + buffer.position());


        System.out.println("=========读取数据");
        // 不传参  代表获取第一个   传参代表指定索引位置
        // 当传参有索引时  position不变化
        System.out.println( (char) buffer.get());
        System.out.println("position:" + buffer.position());

        // 标记  存储当前的位置position
        buffer.mark();

        System.out.println((char) buffer.get());
        System.out.println("position:" + buffer.position());

        // 回退  退回到mark记录的位置
        buffer.reset();
        System.out.println("=========调用reset");
        System.out.println("position:" + buffer.position());

        // clear清空的是索引位置  对象依然存在
        buffer.clear();
        System.out.println("=========调用clear");
        System.out.println("limit:" + buffer.limit());
        System.out.println("position:" + buffer.position());

(3)Selector

 Selector也有比较重要的三个参数 Selector选择器、SelectableChannel可选择的通道、SelectionKey选择键。

将属性为可选择的通道注册进选择器中,Selector可以监听已注册的通道是否有规定操作产生,使用SelectionKey代表具体的事件(连接、接收、读/写 )。

SelectableChannel,是一个抽象类,提供了通道可被选择需要实现的api。

服务通道、选择器注册

    // 服务端通道
    private ServerSocketChannel channel;
    // 多路复用选择器
    private Selector selector;

        
    channel = ServerSocketChannel.open();

    selector = Selector.open();

    SocketAddress address = new InetSocketAddress(6666);
    channel.socket().bind(address);

    channel.configureBlocking(false);
    // 注册通道的可接收事件
    channel.register(selector, SelectionKey.OP_ACCEPT);

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值