我是靠谱客的博主 狂野星星,最近开发中收集的这篇文章主要介绍Channel和Unsafe,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  提起Channel,会想到JDK的NIO类库的重要组成部分:java.nio.SocketChanneljava.nio.ServerSocketChannel,用于非阻塞的I/O操作。
  类似于NIO的Channel,Netty提供自己的Channel及其子类实现,用于异步I/O操作和其他相关的操作。
  Unsafe是内部接口,聚合在Channel中协助进行网络读写相关的操作,因为它的设计初衷就是Channel的内部辅助类,不应该被Netty框架的上层使用者调用。

Channel工作原理

  Channel是Netty抽象出来的网络I/O读写相关的接口,为什么不使用JDK NIO原生的Channel而要另外炉灶,主要原因:
  1)JDK的SocketChannel和ServerSocketChannel没有统一的Channel接口供业务开发者使用,对于用户而言,没有统一的操作视图,使用起来并不方便;
  2)JDK的SocketChannel和ServerSocketChannel的主要职责就是网络I/O操作,由于他们是SPI类接口,由具体的虚拟机厂家来提供,所以通过继承SPI功能类来扩展其功能的难度很大;直接实现ServerSocketChannel和SocketChannel抽象类,其工作量和重新开发一个新的Channel功能类是差不多的;
  3)Netty的Channel需要能够跟Netty的整体架构融合在一起,例如I/O模型、基于ChannelPipeline的定制模型,以及基于元数据描述配置化的TCP参数等,这些JDK的ScoketChannel和ServerSocketChannel都没有提供,需要重新封装;
  4)自定义的Channel,功能实现更加灵活。

  基于上述4个原因,Netty重新设计了Channel接口,并且给予了很多不同的实现。它的设计原理比较简单,但是功能却比较繁杂,主要的设计理念:
  1)在Channel接口层,采用Façade模式进行统一封装,将网络I/O操作、网络I/O相关联的其他操作封装起来,统一对外提供;
  2)Channel接口的定义尽量大而全,为SocketChannel和ServerSocketChannel提供统一的视图,由不同子类实现不同的功能,公共功能在抽象父类中实现,最大程度上实现功能和接口的重用;
  3)具体实现采用聚合而非包含的方式,将相关的功能聚合在Channel中,由Channel统一负责配置和调度。

  io.netty.channel.Channel是Netty网络操作抽象类的主要功能:
  1)网络的读、写;
  2)客户端发起连接、主动关闭连接
  3)链路关闭
  4)获取通信双方的网络地址
  5)获取该Channel的EventLoop
  6)获取缓冲区分类器ByteBufAllocator和pipeline等
  7)获取元数据metadata()
  4)parent():对于服务端Channel为空;对于客户端Channel为创建它的ServerSocketChannel
  5)id() 返回ChannelId对象 Channel的唯一标识符:机器MAC地址+当前进程ID+时间毫秒+时间纳秒+32位随机整数+32位自增序列数。

  Channel类图
这里写图片描述 

  AbstractChannel:采用聚合的方式封装各种功能:

public abstract class AbstractChannel extends DefaultAttributeMap implements Channel {

    ……

    private final Channel parent;
    private final ChannelId id;
    private final Unsafe unsafe;
    private final DefaultChannelPipeline pipeline;
    private final VoidChannelPromise unsafeVoidPromise = new VoidChannelPromise(this, false);
    private final CloseFuture closeFuture = new CloseFuture(this);

    private volatile SocketAddress localAddress;
    private volatile SocketAddress remoteAddress;
    private volatile EventLoop eventLoop;
    private volatile boolean registered;

    /** Cache for the string representation of this channel */
    private boolean strValActive;
    private String strVal;

  可以从成员变量的定义可以看出来,聚合了:parent, id, unsafe, pipeline, eventLoop等。

Unsafe

  Unsafe接口实际上是Channel接口的辅助接口,它不应该被用户直接调用。实际的网络I/O读写操作都是由Unsafe接口及其功能类负责实现的。它的含义不是说它的方法是不安全的,而是说它的接口是给框架本身调用的,不要暴露给业务层调用。
这里写图片描述
  Unsafe的最底层实现类采用了模板方法模式,NioMessageUnsafe绑定到了NioServerSocketChannelNioByteUnsafe绑定到NioSocketChannel,最终的IO读写方法实现在NioServerSocketChannelNioByteUnsafe中,调用了Java的ServerSocketChannelSocketChannel来实现。

最后

以上就是狂野星星为你收集整理的Channel和Unsafe的全部内容,希望文章能够帮你解决Channel和Unsafe所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部