【Java NIO】— Selector 源码分析

 作者简介:大家好,我是码炫码哥,前中兴通讯、美团架构师,现任某互联网公司CTO,兼职码炫课堂主讲源码系列专题


代表作:《jdk源码&多线程&高并发》,《深入tomcat源码解析》,《深入netty源码解析》,《深入dubbo源码解析》,《深入springboot源码解析》,《深入spring源码解析》,《深入redis源码解析》等


联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬。码炫课堂的个人空间-码炫码哥个人主页-面试,源码等

上篇文章详细介绍了 Selector 的核心原理和使用方法,这篇文章我们来深入了解 Selector 的源码,主要讲三个最常用的方法 open()register() 和 selector()

open()

调用 Selector.open() 方法会创建一个 Selector 实例。

public static Selector open() throws IOException {
    return SelectorProvider.provider().openSelector();
}

SelectorProvider 是一个抽象类,它提供了创建 Selector 、ServerSocketChannel、SocketChannel 的方法,采用 Java 的 SPI 方式实现。

public static SelectorProvider provider() {
    synchronized (lock) {
        // 这里保证了只有一个 SelectorProvider
        if (provider != null)
            return provider;
        return AccessController.doPrivileged(
            new PrivilegedAction<SelectorProvider>() {
                public SelectorProvider run() {
                        // 通过配置的 java.nio.channels.spi.SelectorProvider 值注入自定义的SelectorProvider
                        if (loadProviderFromProperty())
                            return provider;
                        // 通过 ServiceLoad 注入,然后获取配置的第一个服务
                        if (loadProviderAsService())
                            return provider;
                        // 默认
                        provider = sun.nio.ch.DefaultSelectorProvider.create();
                        return provider;
                    }
                });
    }
}

如果没有特殊配置,我们一般都是使用默认方法 sun.nio.ch.DefaultSelectorProvider.create()。平台的不同 DefaultSelectorProvider 的实现就不同,码哥这里是 MacBook,实现如下:

public class DefaultSelectorProvider {
    private DefaultSelectorProvider() {
    }

    public static SelectorProvider create() {
        return new KQueueSelectorProvider();
    }
}

从这里我们就可以看出,MacOS 使用的多路复用是 kqueue。对于 Windows 和 Linux 码哥也找到了相对应的实现。

// Windows
public class DefaultSelectorProvider {
    private DefaultSelectorProvider() { }
    public static SelectorProvider create() {
        return new sun.nio.ch.WindowsSelectorProvider();
    }
}
// Linux
public class DefaultSelectorProvider {

    private DefaultSelectorProvider() { }

    @SuppressWarnings("unchecked")
    private static SelectorProvider createProvider(String cn) {
        Class<SelectorProvider> c;
        try {
            c = (Class<SelectorProvider>)Class.forName(cn);
        } catch (ClassNotFoundException x) {
            throw new AssertionError(x);
        }
        try {
            return c.newInstance();
        } catch (IllegalAccessException | InstantiationException x) {
            throw new AssertionError(x);
        }
    }

    public static SelectorProvider create() {
        String osname = AccessController
            .doPrivileged(new GetPropertyAction("os.name"));
        if (osname.equals("SunOS"))
           
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值