NIO源码之Selector.open()

今天在练习用nio写一个聊天室时,突然想到了一个问题,我们在客户端和服务端都使用Selector,那这个Selector是否是同一个呢,它是怎么创建的呢,所以我自己看了看源码。

Selector类里有静态方法

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

它是应用了 SelectorProvider类的provider()方法

SelectorProvider是一个抽象类 provider()方法如下

public static SelectorProvider provider() {
synchronized (lock) {//这是一个类锁 private static final Object lock = //new Object(); 防止多线程下干扰
if (provider != null)//private static SelectorProvider provider = null;
return provider;//这是一个单例模式
return AccessController.doPrivileged(//检查了权限
new PrivilegedAction() {
public SelectorProvider run() {
if (loadProviderFromProperty())//从配置文件中读取见下文
return provider;
if (loadProviderAsService())//见下面分析
return provider;
provider = sun.nio.ch.DefaultSelectorProvider.create();
//返回了系统默认的SelectorProvider
return provider;
}
});
}
}

private static boolean loadProviderFromProperty() {
String cn = System.getProperty(“java.nio.channels.spi.SelectorProvider”);
if (cn == null)
return false;
try {
Class<?> c = Class.forName(cn, true,
ClassLoader.getSystemClassLoader());
provider = (SelectorProvider)c.newInstance();
return true;
} catch (ClassNotFoundException x) {
throw new ServiceConfigurationError(null, x);
} catch (IllegalAccessException x) {
throw new ServiceConfigurationError(null, x);
} catch (InstantiationException x) {
throw new ServiceConfigurationError(null, x);
} catch (SecurityException x) {
throw new ServiceConfigurationError(null, x);
}
}
获取了SelectorProvider的全类名 然后拿到系统的类文件加载器通过反射,拿到实例。

private static boolean loadProviderAsService() {

    ServiceLoader<SelectorProvider> sl =
        ServiceLoader.load(SelectorProvider.class,
                           ClassLoader.getSystemClassLoader());
    Iterator<SelectorProvider> i = sl.iterator();
    for (;;) {
        try {
            if (!i.hasNext())
                return false;
            provider = i.next();
            return true;
        } catch (ServiceConfigurationError sce) {
            if (sce.getCause() instanceof SecurityException) {
                // Ignore the security exception, try the next provider
                continue;
            }
            throw sce;
        }
    }
}

从服务加在器中加在是否有服务中已经安装了Provider的jar包,如果有则返回,没有则抛异常

由此可见Selector由系统提供的SelectorProvider获得,与你所使用的系统有关,Provider是一个单例模式,所以只有一个provider,获得一个相同的Selector

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值