美文网首页
netty基础-NIO的selector

netty基础-NIO的selector

作者: cjxz | 来源:发表于2019-01-15 15:32 被阅读0次

使用NIO的时候会创建叫号大厅Selector。这是一个单线程不停的循环读取客户端发送过来的请求。然后将客户端的请求保存到SelectionKey里面。

Selector叫号大厅
  • Selector.open();
    selector = Selector.open();
    public static Selector open() throws IOException {
        return SelectorProvider.provider().openSelector();
    }
    //SelectorProvider定义了创建selector、ServerSocketChannel、SocketChannel等方法.采用Java的 Service Provider Interface (SPI) 方式实现
    public static SelectorProvider provider() {
        synchronized (lock) {
            if (provider != null)
                return provider;
            return AccessController.doPrivileged(
                new PrivilegedAction<SelectorProvider>() {
                    public SelectorProvider run() {
                            if (loadProviderFromProperty())
                                return provider;
                            if (loadProviderAsService())
                                return provider;
                            provider = sun.nio.ch.DefaultSelectorProvider.create();
                            return provider;
                        }
                    });
        }
    }
    public static SelectorProvider create() {
        return new KQueueSelectorProvider();
    }
    public AbstractSelector openSelector() throws IOException {
        return new KQueueSelectorImpl(this);
    }

上面是创建Selector的过程。可以看到Selector是new KQueueSelectorProvider生成的,然后调用open()方法,open()方法调用是new KQueueSelectorImpl(this)此处的this是KQueueSelectorProvider对象。在KQueueSelectorImpl这个类里面有几个属性。看名字应该是队列。

    protected int fd0;
    protected int fd1;
    KQueueArrayWrapper kqueueWrapper;
    private int totalChannels;
    private HashMap<Integer, KQueueSelectorImpl.MapEntry> fdMap;
    private boolean closed = false;
    private Object interruptLock = new Object();
    private boolean interruptTriggered = false;
    private long updateCount;

可以看到上面的selector = Selector.open();就是实例一个KQueueSelectorImpl

  • server.register(selector, SelectionKey.OP_ACCEPT);
    register的过程就是注册SelectionKey
if (k == null) {
    // New registration
    synchronized (keyLock) {
        if (!isOpen())
            throw new ClosedChannelException();
        k = ((AbstractSelector)sel).register(this, ops, att);
        addKey(k);
    }
}
//AbstractSelectableChannel:这个参数是ServerSocketChannel
//第二个参数是注册事件的类型,有read write accept等
//通过这个方法可以看到register的过程是就是将ServerSocketChannel注册到Selector上面
protected final SelectionKey register(AbstractSelectableChannel var1, int var2, Object var3) {
    if (!(var1 instanceof SelChImpl)) {
        throw new IllegalSelectorException();
    } else {
        SelectionKeyImpl var4 = new SelectionKeyImpl((SelChImpl)var1, this);
        var4.attach(var3);
        Set var5 = this.publicKeys;
        synchronized(this.publicKeys) {
            this.implRegister(var4);
        }

        var4.interestOps(var2);
        return var4;
    }
}

SelectionKeyImpl对象包含了ServerSocketChannel;Selector这样在使用时可以从SelectionKey里面获得Channel,进而读取Channel里面的数据

    //这是SelectionKeyImpl内部的属性
    final SelChImpl channel;  //这个是Channel如果是服务端的话都是ServerSocketChannel
    public final SelectorImpl selector;  //这是Selector
    private int index;
    private volatile int interestOps;
    private int readyOps;

分析到这可以知道在SelectionKey里面是有Channel对象的,如果使用ServerSocketChannel进行register那么Selectionkey里面保存的就是ServerSocketChannel。如果使用SocketChannel进行register那么SelectionKey里面保存的就是SocketChannel。在回到前一篇《netty基础-NIO简单demo》首先是server.register(selector, SelectionKey.OP_ACCEPT);这是如果接收到Accept事件,那么SelectionKey里面存放的是ServerSocketChannel。然后在Accept事件中我们又绑定了read事件。这是使用的client.register(selector,SelectionKey.OP_READ);那么在read事件中获得的Channel就是SocketChannel

相关文章

  • netty基础-NIO的selector

    使用NIO的时候会创建叫号大厅Selector。这是一个单线程不停的循环读取客户端发送过来的请求。然后将客户端的请...

  • 多线程Reactor模式及Netty线程模型

    Netty是一款高效的NIO框架和工具,基于Java NIO实现,Java NIO的Selector给Reacto...

  • Netty组件介绍

    在学习Netty之前,建议首先学习一个NIO,对关键的NIO组件有一个清醒认识 Buffer Selector 总...

  • Netty组件介绍

    在学习Netty之前,建议首先学习一个NIO,对关键的NIO组件有一个清醒认识 Buffer Selector 总...

  • Netty服务器源码分析

    本文基于Netty 4 在讨论Netty服务器启动之前,先回顾一下服务端使用Java nio selector的启...

  • netty 小结

    netty 关键词: 网络编程 nio 事件驱动Rector 和selector机制 相关流程: 引导器BootS...

  • Selector.select()

    Netty的底层依然是依赖于JDK的NIO . 开发NIO服务端的代码如下所示 本篇文章就来讲解下selector...

  • Netty与Reactor 模式

    前言 Netty 的线程模型是基于NIO的Selector 构建的,使用了异步驱动的Reactor 模式来构建的线...

  • Netty:初识Netty

    前文总结了NIO的内容,有了NIO的一些基础之后,我们就可以来看下Netty。Netty是Java领域的高性能网络...

  • Netty基础知识之NIO

    Netty基础知识之NIO Netty是一款提供异步的、事件驱动的网络应用程序框架和工具,是基于NIO客户端、服务...

网友评论

      本文标题:netty基础-NIO的selector

      本文链接:https://www.haomeiwen.com/subject/pnjydqtx.html