[編織訊息架構][netty源碼分析]5 EventLoopGroup 實作類別NioEventLoopGroup職責與實現

來源:互聯網
上載者:User

標籤:ada   public   cti   loop   如何   狀態   config   比較   sel   

分析NioEventLoopGroup最主有兩個疑問

1.next work如何分配NioEventLoop

2.boss group 與child group 是如何協作啟動並執行

 

從EventLoopGroup介面約定通過register方法從channel或promise轉換成ChannelFuture對象

next方法就是用來分配NioEventLoop

public interface EventLoopGroup extends EventExecutorGroup {    @Override    EventLoop next();        ChannelFuture register(Channel channel);    ChannelFuture register(ChannelPromise promise);    @Deprecated    ChannelFuture register(Channel channel, ChannelPromise promise);}

為了節省篇副,做了代碼整理

1.NioEventLoopGroup構造時綁定SelectorProvider.provider(),通過newChild產生單個EventLoop

2.next實現是個環形迴圈

3.register方法是將channel轉換成ChannelFuture

讀者如果感興趣可以在這幾個方法打上斷點看看

public class NioEventLoopGroup extends MultithreadEventLoopGroup {    public NioEventLoopGroup(int nThreads, Executor executor) {        this(nThreads, executor, SelectorProvider.provider());    }    @Override    protected EventLoop newChild(Executor executor, Object... args) throws Exception {        return new NioEventLoop(this, executor, (SelectorProvider) args[0],            ((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);    }    /////////////////////////////GenericEventExecutorChooser實現next//////////////////////////////////    @Override    public EventExecutor next() {        return executors[Math.abs(idx.getAndIncrement() % executors.length)];    }        /////////////////////////////SingleThreadEventLoop實現register//////////////////////////////////     @Override    public ChannelFuture register(Channel channel) {        return register(new DefaultChannelPromise(channel, this));    }    @Override    public ChannelFuture register(final ChannelPromise promise) {        ObjectUtil.checkNotNull(promise, "promise");        promise.channel().unsafe().register(this, promise);        return promise;    }}

我們用過程的方式來類比NioEventLoopGroup使用

如果讀者有印象netty server 至少有兩組NioEventLoopGroup 一個是boss 另一個是child

public class TestBossChildGroup {    static SocketAddress address = new InetSocketAddress("localhost", 8877);    @Test    public void server() throws IOException {        SelectorProvider bossProvider = SelectorProvider.provider();        SelectorProvider childProvider = SelectorProvider.provider();        int count = 2;        AbstractSelector bossSelector = bossProvider.openSelector();        AbstractSelector[] childSelectors = new AbstractSelector[count];        for (int i = 0; i < count; i++) {            childSelectors[i] = childProvider.openSelector();        }        //server綁定訪問連接埠 並向Selector註冊OP_ACCEPT        ServerSocketChannel serverSocketChannel = bossProvider.openServerSocketChannel();        serverSocketChannel.configureBlocking(false);        serverSocketChannel.bind(address);        serverSocketChannel.register(bossSelector, SelectionKey.OP_ACCEPT);                  int i = 0;        while (true) {            int s = bossSelector.select(300);            if (s > 0) {            Set<SelectionKey> keys = bossSelector.selectedKeys();            Iterator<SelectionKey> it = keys.iterator();            while (it.hasNext()) {                SelectionKey key = it.next();                //為什麼不用elseIf 因為 key interestOps 是多重疊狀態,一次返回多個操作                if (key.isAcceptable()) {                System.out.println("isAcceptable");                //這裡比較巧妙,註冊OP_READ交給別一個Selector處理                key.channel().register(childSelectors[i++ % count], SelectionKey.OP_READ);                }                //這部分是child eventLoop處理                if (key.isConnectable()) {                System.out.println("isConnectable");                }                if (key.isWritable()) {                System.out.println("isWritable");                }                if (key.isReadable()) {                System.out.println("isReadable");                }                key.interestOps(~key.interestOps());                it.remove();            }            }        }    }    @Test    public void client() throws IOException {        SocketChannel clientSocketChannel = SelectorProvider.provider().openSocketChannel();        clientSocketChannel.configureBlocking(true);        clientSocketChannel.connect(address);    }}

 

[編織訊息架構][netty源碼分析]5 EventLoopGroup 實作類別NioEventLoopGroup職責與實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.