返回顶部
首页 > 资讯 > 精选 >NioEventLoop的run方法实例分析
  • 317
分享到

NioEventLoop的run方法实例分析

2023-06-29 15:06:01 317人浏览 安东尼
摘要

这篇文章主要介绍了NIOEventLoop的run方法实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇NioEventLoop的run方法实例分析文章都会有所收获,下面我们一起来看看吧。Netty事件循环

这篇文章主要介绍了NIOEventLoop的run方法实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇NioEventLoop的run方法实例分析文章都会有所收获,下面我们一起来看看吧。

Netty事件循环主逻辑

Netty 事件循环主逻辑在 NioEventLoop.run 中的 processSelectedKeys函数中

protected void run() {      //主循环不断读取IO事件和task,因为 EventLoop 也是 juc 的 ScheduledExecutorService 实现        for (;;) {            try {                switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {                    case SelectStrategy.CONTINUE:                        continue;                    case SelectStrategy.SELECT:                        select(wakenUp.getAndSet(false));                                                if (wakenUp.get()) {                            selector.wakeup();                        }                        // fall through                    default:                }                cancelledKeys = 0;                needsToSelectAgain = false;            // IO事件占总执行时间的百分比 */                final int ioRatio = this.ioRatio;                if (ioRatio == 100) {                    try {                        processSelectedKeys();                    } finally {                        // Ensure we always run tasks.                        runAllTasks();                    }                } else {                    final long iOStartTime = System.nanoTime();                    try {                        processSelectedKeys();                    } finally {                        // Ensure we always run tasks.                        final long ioTime = System.nanoTime() - ioStartTime;                        runAllTasks(ioTime * (100 - ioRatio) / ioRatio);                    }                }            } catch (Throwable t) {                handleLoopException(t);            }            // Always handle shutdown even if the loop processing threw an exception.            try {                if (isshuttingDown()) {                    closeAll();                    if (confirmShutdown()) {                        return;                    }                }            } catch (Throwable t) {                handleLoopException(t);            }        }    }

processSelectedKeys 函数 执行时会判断是否执行优化的版本,即判断 SelectedSelectionKeySet 是否为空。

是否开启优化取决于是否设置了环境变量  io.netty.noKeySetOptimization ,默认是 false 代表开启

private static final boolean DISABLE_KEYSET_OPTIMIZATION =            SystemPropertyUtil.getBoolean("io.netty.noKeySetOptimization", false);

原理是通过反射的方式设置 eventLoop绑定的selector中的 selecTKEys属性 为 SelectedSelectionKeySet ,好处是不用 迭代  selector.selectedKeys()

初始化 EventLoop

注入时机为初始化 EventLoop 的时候

private SelectorTuple openSelector() {        12      //注入逻辑40         Object maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {            @Override            public Object run() {                try {                    Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");                    Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");                    Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField);                    if (cause != null) {                        return cause;                    }                    cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField);                    if (cause != null) {                        return cause;                    }                    selectedKeysField.set(unwrappedSelector, selectedKeySet);                    publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);                    return null;                } catch (NoSuchFieldException e) {                    return e;                } catch (IllegalAccessException e) {                    return e;                }            }        });        ........78     }

处理读事件

处理读事件主要在processSelectedKey 中 ,分别对 读、写、连接事件进行了处理。

private void processSelectedKeysOptimized() {        for (int i = 0; i < selectedKeys.size; ++i) {            final SelectionKey k = selectedKeys.keys[i];            // null out entry in the array to allow to have it GC'ed once the Channel close            // See https://GitHub.com/netty/netty/issues/2363            selectedKeys.keys[i] = null;            final Object a = k.attachment();            if (a instanceof AbstractNiochannel) {                //分别处理每个channel的事件                processSelectedKey(k, (AbstractNioChannel) a);            } else {                @SuppressWarnings("unchecked")                NioTask<SelectableChannel> task = (NioTask<SelectableChannel>) a;                processSelectedKey(k, task);            }            if (needsToSelectAgain) {                // null out entries in the array to allow to have it GC'ed once the Channel close                // See Https://github.com/netty/netty/issues/2363                selectedKeys.reset(i + 1);                selectAgain();                i = -1;            }        }    }    private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {        final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();        if (!k.isValid()) {            final EventLoop eventLoop;            try {                eventLoop = ch.eventLoop();            } catch (Throwable ignored) {                // If the channel implementation throws an exception because there is no event loop, we ignore this                // because we are only trying to determine if ch is reGIStered to this event loop and thus has authority                // to close ch.                return;            }            // Only close ch if ch is still registered to this EventLoop. ch could have deregistered from the event loop            // and thus the SelectionKey could be cancelled as part of the deregistration process, but the channel is            // still healthy and should not be closed.            // See https://github.com/netty/netty/issues/5125            if (eventLoop != this || eventLoop == null) {                return;            }            // close the channel if the key is not valid anymore            unsafe.close(unsafe.voidPromise());            return;        }        try {            int readyOps = k.readyOps();            // We first need to call finishConnect() before try to trigger a read(...) or write(...) as otherwise            // the NIO jdk channel implementation may throw a NotYetConnectedException.            if ((readyOps & SelectionKey.OP_CONNECT) != 0) {                // remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking                // See https://github.com/netty/netty/issues/924                int ops = k.interestOps();                ops &= ~SelectionKey.OP_CONNECT;                k.interestOps(ops);          //处理了连接事件                unsafe.finishConnect();            }            // Process OP_WRITE first as we may be able to write some queued buffers and so free memory.            if ((readyOps & SelectionKey.OP_WRITE) != 0) {                // Call forceFlush which will also take care of clear the OP_WRITE once there is nothing left to write
 //将要写入的buffer flush掉          ch.unsafe().forceFlush();            }            // Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead            // to a spin loop            if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {           //回调 pipeline 上所有的 ChannelInboundHandler 的 fireChannelRead  和 channelReadComplete 函数                unsafe.read();            }        } catch (CancelledKeyException ignored) {            unsafe.close(unsafe.voidPromise());        }    }

注意 

NioServerSocketChannel 和 NioSocketChannel 都是 同样的 处理逻辑, 不同的是  前者 只关注 OP_ACCEPT 和 OP_READ事件, 后者 关注  OP_READ、OP_WRITE、OP_CONNECT事件

当NioServerSocketChannel 发生 OP_ACCEPT事件时 会 触发

 AbstractNioChannel.NioUnsafe.read ->  NioSctpServerChannel.doReadMessages(List<Object>)  -> ServerBootstrapAcceptor.channelRead ,

将受到的 NioSocketChannel 注册到 childEventLoop 。

关于“NioEventLoop的run方法实例分析”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“NioEventLoop的run方法实例分析”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: NioEventLoop的run方法实例分析

本文链接: https://lsjlt.com/news/325617.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • NioEventLoop的run方法实例分析
    这篇文章主要介绍了NioEventLoop的run方法实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇NioEventLoop的run方法实例分析文章都会有所收获,下面我们一起来看看吧。Netty事件循环...
    99+
    2023-06-29
  • Netty事件循环主逻辑NioEventLoop的run方法分析
    目录Netty事件循环主逻辑初始化 EventLoop处理读事件注意 Netty事件循环主逻辑 Netty 事件循环主逻辑在 NioEventLoop.run 中...
    99+
    2024-04-02
  • load方法实例分析
    这篇“load方法实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“load方法实例分...
    99+
    2024-04-02
  • Java的Arrays.sort()方法实例分析
    本篇内容主要讲解“Java的Arrays.sort()方法实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java的Arrays.sort()方法实例分析”吧!首先看代码:// ...
    99+
    2023-06-29
  • Netty源码解析NioEventLoop创建的构造方法
    目录NioEventLoopGroup之NioEventLoop的创建我们来看第二步构造NioEventLoop我们继续跟到NioEventLoop的构造方法最后跟到Abstract...
    99+
    2024-04-02
  • Netty源码分析NioEventLoop线程的启动
    目录NioEventLoop开启方法跟进 inEventLoop()方法跟一下addTask(task)回顾一下初始构造方法我们跟进doStartThread()方法中回顾...
    99+
    2024-04-02
  • springboot run启动时指定spring.profiles.active的示例分析
    今天就跟大家聊聊有关springboot run启动时指定spring.profiles.active的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Maven启动指定Pro...
    99+
    2023-06-26
  • Netty分布式NioEventLoop任务队列执行的方法
    这篇文章主要介绍“Netty分布式NioEventLoop任务队列执行的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Netty分布式NioEventLoop任务队列执行的方法”文章能帮助大家解...
    99+
    2023-06-29
  • HTML使用方法实例分析
    本文小编为大家详细介绍“HTML使用方法实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“HTML使用方法实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。首先使用 V...
    99+
    2024-04-02
  • JavaScript中Switch方法实例分析
    本篇内容主要讲解“JavaScript中Switch方法实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中Switch方法实例分析”吧...
    99+
    2024-04-02
  • Javascript队列方法实例分析
    这篇文章主要介绍“Javascript队列方法实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript队列方法实例分析”文章能帮助大家解决问题。J...
    99+
    2024-04-02
  • URL去重方法实例分析
    这篇文章主要介绍“URL去重方法实例分析”,在日常操作中,相信很多人在URL去重方法实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”URL去重方法实例分析”的疑惑有所帮助!接下来,请跟着小编一起来学习吧...
    99+
    2023-06-27
  • thinkphp中add方法实例分析
    这篇文章主要介绍了thinkphp中add方法实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇thinkphp中add方法实例分析文章都会有所收获,下面我们一起来看看吧。thinkphp中add()方法的...
    99+
    2023-06-29
  • python实操方法案例分析
    本篇内容介绍了“python实操方法案例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!任务1、我的咖啡馆你做主元组coffee_name...
    99+
    2023-06-29
  • win7安装方法实例分析
    今天小编给大家分享一下win7安装方法实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。win7安装教程第一步:在本站选...
    99+
    2023-07-01
  • Java方法使用实例分析
    这篇“Java方法使用实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java方法使用实例分析”文章吧。一、方法的概念...
    99+
    2023-06-30
  • Java Object类方法实例分析
    本文小编为大家详细介绍“Java Object类方法实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java Object类方法实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.equals方法1...
    99+
    2023-06-30
  • Android中TelephonyManager类的方法实例分析
    本文实例讲述了Android中TelephonyManager类的方法。分享给大家供大家参考。具体如下: TelephonyManager类主要提供了一系列用于访问与手机通讯相...
    99+
    2022-06-06
    方法 Android
  • python int返回的方法实例分析
    今天小编给大家分享一下python int返回的方法实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1、int额外的方...
    99+
    2023-06-30
  • jQuery中extend()与工具方法、实例方法的示例分析
    这篇文章主要介绍jQuery中extend()与工具方法、实例方法的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!具体如下:使用jQuery的时候会发现,jQuery中有的函...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作