最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Netty事件循環(huán)主邏輯NioEventLoop的run方法分析

 更新時間:2022年03月24日 18:24:13   作者:liron  
這篇文章主要介紹了Netty事件循環(huán)主邏輯NioEventLoop的run方法分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

Netty事件循環(huán)主邏輯

Netty 事件循環(huán)主邏輯在 NioEventLoop.run 中的 processSelectedKeys函數(shù)中

protected void run() {
      //主循環(huán)不斷讀取IO事件和task,因為 EventLoop 也是 juc 的 ScheduledExecutorService 實現(xiàn)
        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事件占總執(zhí)行時間的百分比 */
                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 函數(shù) 執(zhí)行時會判斷是否執(zhí)行優(yōu)化的版本,即判斷 SelectedSelectionKeySet 是否為空。

是否開啟優(yōu)化取決于是否設置了環(huán)境變量  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 函數(shù)
                unsafe.read();
            }
        } catch (CancelledKeyException ignored) {
            unsafe.close(unsafe.voidPromise());
        }
    }

注意 

NioServerSocketChannel 和 NioSocketChannel 都是 同樣的 處理邏輯, 不同的是  前者 只關注 OP_ACCEPT 和 OP_READ事件, 后者 關注  OP_READ、OP_WRITE、OP_CONNECT事件

當NioServerSocketChannel 發(fā)生 OP_ACCEPT事件時 會 觸發(fā)

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

將受到的 NioSocketChannel 注冊到 childEventLoop 。

以上就是Netty事件循環(huán)主邏輯NioEventLoop的run方法分析的詳細內容,更多關于Netty循環(huán)邏輯NioEventLoop run方法的資料請關注腳本之家其它相關文章!

相關文章

  • 一文詳解Java線程的6種狀態(tài)與生命周期

    一文詳解Java線程的6種狀態(tài)與生命周期

    一個線程在給定的時間點只能處于一種狀態(tài)。線程可以有6種狀態(tài):New、Runnable、Blocked、Waiting、Timed?waiting和Terminated。本文將詳細講解這6種狀態(tài),需要的可以參考一下
    2022-05-05
  • 一文掌握Spring?Boot?日志文件

    一文掌握Spring?Boot?日志文件

    日志是程序的重要組成部分,日志對于我們來說,最主要的用途就是排除和定位問題,這篇文章主要介紹了Spring?Boot?日志文件,需要的朋友可以參考下
    2023-03-03
  • springboot整合redis過期key監(jiān)聽實現(xiàn)訂單過期的項目實踐

    springboot整合redis過期key監(jiān)聽實現(xiàn)訂單過期的項目實踐

    現(xiàn)在各種電商平臺都有自己的訂單過期時間設置,那么如何設置訂單時間過期呢,本文主要介紹了springboot整合redis過期key監(jiān)聽實現(xiàn)訂單過期的項目實踐,感興趣的可以了解一下
    2023-12-12
  • Spring Boot如何使用httpcomponents實現(xiàn)http請求

    Spring Boot如何使用httpcomponents實現(xiàn)http請求

    這篇文章主要介紹了Spring Boot使用httpcomponents實現(xiàn)http請求的示例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 一篇文章教你如何用多種迭代寫法實現(xiàn)二叉樹遍歷

    一篇文章教你如何用多種迭代寫法實現(xiàn)二叉樹遍歷

    這篇文章主要介紹了C語言實現(xiàn)二叉樹遍歷的迭代算法,包括二叉樹的中序遍歷、先序遍歷及后序遍歷等,是非常經典的算法,需要的朋友可以參考下
    2021-08-08
  • com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的區(qū)別及設定serverTimezone的方法

    com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的區(qū)

    這篇文章主要介紹了com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver的區(qū)別以及設定serverTimezone的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • 使用Mybatis-plus清空表數(shù)據的操作方法

    使用Mybatis-plus清空表數(shù)據的操作方法

    MyBatis 是一個基于 java 的持久層框架,它內部封裝了 jdbc,極大提高了我們的開發(fā)效率,文中給大家介紹了MybatisPlus常用API-增刪改查功能,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Spring避免循環(huán)依賴的策略詳解

    Spring避免循環(huán)依賴的策略詳解

    在Spring框架中,循環(huán)依賴是指兩個或多個bean相互依賴對方,形成一個閉環(huán),這在應用啟動時可能導致BeanCurrentlyInCreationException異常,本文給大家介紹了Spring中如何避免循環(huán)依賴,需要的朋友可以參考下
    2024-02-02
  • 解決nacos的yml配置文件解析@開頭的值啟動報錯問題

    解決nacos的yml配置文件解析@開頭的值啟動報錯問題

    這篇文章主要介紹了解決nacos的yml配置文件解析@開頭的值啟動報錯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • SpringBoot使用SchedulingConfigurer實現(xiàn)多個定時任務多機器部署問題(推薦)

    SpringBoot使用SchedulingConfigurer實現(xiàn)多個定時任務多機器部署問題(推薦)

    這篇文章主要介紹了SpringBoot使用SchedulingConfigurer實現(xiàn)多個定時任務多機器部署問題,定時任務多機器部署解決方案,方式一拆分,單獨拆分出來,單獨跑一個應用,方式二是基于aop攔截處理(搶占執(zhí)行),只要有一個執(zhí)行,其它都不執(zhí)行,需要的朋友可以參考下
    2023-01-01

最新評論

沭阳县| 福清市| 孝感市| 上林县| 灌南县| 白银市| 达孜县| 本溪市| 苍山县| 彝良县| 麻阳| 柘城县| 区。| 壶关县| 纳雍县| 横山县| 江西省| 新宁县| 府谷县| 独山县| 镇康县| 罗平县| 临清市| 嘉定区| 搜索| 康平县| 峨山| 同江市| 武山县| 县级市| 福安市| 阜阳市| 离岛区| 南江县| 鄂尔多斯市| 科技| 仲巴县| 柞水县| 广灵县| 普宁市| 哈密市|