当前位置: 首页 > article >正文

Netty中用到了哪些设计模式

Netty作为一个高性能的网络通信框架,里面有很多优秀的代码值得我们学习,今天我们一起看下Netty中用到了哪些设计模式。

一、单例模式

Netty通过 NioEventLoop 将通道注册到选择器,并在事件循环中多路复用它们。其中提供了一个选择策略对象 SelectStrategy,它只有一个默认实现:DefaultSelectStrategy。

/**
 * Default select strategy.
 */
final class DefaultSelectStrategy implements SelectStrategy {
    static final SelectStrategy INSTANCE = new DefaultSelectStrategy();

    private DefaultSelectStrategy() { }

    @Override
    public int calculateStrategy(IntSupplier selectSupplier, boolean hasTasks) throws Exception {
        return hasTasks ? selectSupplier.get() : SelectStrategy.SELECT;
    }
}

还有 ReadTimeoutException 和 WriteTimeoutException

/**
 * A {@link TimeoutException} raised by {@link ReadTimeoutHandler} when no data
 * was read within a certain period of time.
 */
public final class ReadTimeoutException extends TimeoutException {

    private static final long serialVersionUID = 169287984113283421L;

    public static final ReadTimeoutException INSTANCE = PlatformDependent.javaVersion() >= 7 ?
            new ReadTimeoutException(true) : new ReadTimeoutException();

    ReadTimeoutException() { }

    private ReadTimeoutException(boolean shared) {
        super(shared);
    }
}
/**
 * A {@link TimeoutException} raised by {@link WriteTimeoutHandler} when a write operation
 * cannot finish in a certain period of time.
 */
public final class WriteTimeoutException extends TimeoutException {

    private static final long serialVersionUID = -144786655770296065L;

    public static final WriteTimeoutException INSTANCE = PlatformDependent.javaVersion() >= 7 ?
            new WriteTimeoutException(true) : new WriteTimeoutException();

    private WriteTimeoutException() { }

    private WriteTimeoutException(boolean shared) {
        super(shared);
    }
}

二、工厂模式

工厂模式是非常常见的一种模式,Netty中也使用到,比如 上面提到的选择策略工厂: DefaultSelectStrategyFactory

/**
 * Factory which uses the default select strategy.
 */
public final class DefaultSelectStrategyFactory implements SelectStrategyFactory {
    public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory();

    private DefaultSelectStrategyFactory() { }

    @Override
    public SelectStrategy newSelectStrategy() {
        return DefaultSelectStrategy.INSTANCE;
    }
}

三、策略模式

在默认的事件执行选择工厂 DefaultEventExecutorChooserFactory 的 newChooser 方法中,根据数组参数的长度是否是2的幂 来选择不同的 EventExecutorChooser。两种方式都是简单的轮询方式,只是方式不同。

    @Override
    public EventExecutorChooser newChooser(EventExecutor[] executors) {
        if (isPowerOfTwo(executors.length)) {
            return new PowerOfTwoEventExecutorChooser(executors);
        } else {
            return new GenericEventExecutorChooser(executors);
        }
    }

private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {
        private final AtomicInteger idx = new AtomicInteger();
        private final EventExecutor[] executors;

        PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

        @Override
        public EventExecutor next() {
            return executors[idx.getAndIncrement() & executors.length - 1];
        }
    }

    private static final class GenericEventExecutorChooser implements EventExecutorChooser {
        // Use a 'long' counter to avoid non-round-robin behaviour at the 32-bit overflow boundary.
        // The 64-bit long solves this by placing the overflow so far into the future, that no system
        // will encounter this in practice.
        private final AtomicLong idx = new AtomicLong();
        private final EventExecutor[] executors;

        GenericEventExecutorChooser(EventExecutor[] executors) {
            this.executors = executors;
        }

        @Override
        public EventExecutor next() {
            return executors[(int) Math.abs(idx.getAndIncrement() % executors.length)];
        }
    }

四、装饰者模式

WrappedByteBuf 就是对 ByteBuf的装饰,来实现对它的增加。
class WrappedByteBuf extends ByteBuf {

    protected final ByteBuf buf;

    protected WrappedByteBuf(ByteBuf buf) {
        if (buf == null) {
            throw new NullPointerException("buf");
        }
        this.buf = buf;
    }

......
}

五、责任链模式

ChannelPipeline 就是用到了责任链模式,所谓的责任链模式是指:它允许多个对象在处理请求时形成一条链,每个对象都有机会处理请求,将请求沿着链传递,直到有一个对象处理它为止。

/**
 * The default {@link ChannelPipeline} implementation.  It is usually created
 * by a {@link Channel} implementation when the {@link Channel} is created.
 */
public class DefaultChannelPipeline implements ChannelPipeline {

    static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);

    private static final String HEAD_NAME = generateName0(HeadContext.class);
    private static final String TAIL_NAME = generateName0(TailContext.class);

    private static final FastThreadLocal<Map<Class<?>, String>> nameCaches =
            new FastThreadLocal<Map<Class<?>, String>>() {
        @Override
        protected Map<Class<?>, String> initialValue() {
            return new WeakHashMap<Class<?>, String>();
        }
    };

    private static final AtomicReferenceFieldUpdater<DefaultChannelPipeline, MessageSizeEstimator.Handle> ESTIMATOR =
            AtomicReferenceFieldUpdater.newUpdater(
                    DefaultChannelPipeline.class, MessageSizeEstimator.Handle.class, "estimatorHandle");
    final HeadContext head;
    final TailContext tail;

    private final Channel channel;
    private final ChannelFuture succeededFuture;
    private final VoidChannelPromise voidPromise;
    private final boolean touch = ResourceLeakDetector.isEnabled();

    private Map<EventExecutorGroup, EventExecutor> childExecutors;
    private volatile MessageSizeEstimator.Handle estimatorHandle;
    private boolean firstRegistration = true;

    /**
     * This is the head of a linked list that is processed by {@link #callHandlerAddedForAllHandlers()} and so process
     * all the pending {@link #callHandlerAdded0(AbstractChannelHandlerContext)}.
     *
     * We only keep the head because it is expected that the list is used infrequently and its size is small.
     * Thus full iterations to do insertions is assumed to be a good compromised to saving memory and tail management
     * complexity.
     */
    private PendingHandlerCallback pendingHandlerCallbackHead;

    /**
     * Set to {@code true} once the {@link AbstractChannel} is registered.Once set to {@code true} the value will never
     * change.
     */
    private boolean registered;

    protected DefaultChannelPipeline(Channel channel) {
        this.channel = ObjectUtil.checkNotNull(channel, "channel");
        succeededFuture = new SucceededChannelFuture(channel, null);
        voidPromise =  new VoidChannelPromise(channel, true);

        tail = new TailContext(this);
        head = new HeadContext(this);

        head.next = tail;
        tail.prev = head;
    }


http://www.kler.cn/a/299783.html

相关文章:

  • Python设计模式 - 组合模式
  • 我的2024年博客总结(在工作、博客和生活中找到自己的生活节奏)
  • 【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.30 性能巅峰:NumPy代码优化全攻略
  • Go反射指南
  • 供应链系统设计-供应链中台系统设计(十)- 清结算中心概念片篇
  • 实时数据处理与模型推理:利用 Spring AI 实现对数据的推理与分析
  • 机器学习,深度学习,AGI,AI的概念和区别
  • git使用基础教程
  • 【系统架构设计师】享元模式
  • 机器学习中的聚类艺术:探索数据的隐秘之美
  • 【视频讲解】Python贝叶斯卷积神经网络分类胸部X光图像数据集实例
  • 3D技术在电商行业的应用有哪些?
  • 大厂中秋福利哪家强?字节发被子,京东联名三星堆!网友:最强的还是我们......
  • SpringBoot打包部署,打包成jar和war有所不同?
  • 人工智能领域的AGI指的是什么?
  • Kotlin 特性之扩展函数
  • 【Linux系统学习】2.Linux基础命令
  • C++那些事之精选68道面试题
  • 部署若依Spring boot项目
  • 分享 6 款在日常电脑办公中频繁使用的软件
  • SQL(结构性查询语句)
  • Vm软件安装_链接相机
  • 微信如何转发群消息给其他群或其他好友?
  • SSL 证书 | 免费获取与自动续期全攻略
  • 微型神经网络如何表示基本函数
  • 三、Maven工程的构建