美文网首页
JAVA NIO SELECTOR

JAVA NIO SELECTOR

作者: zh_harry | 来源:发表于2018-11-07 13:25 被阅读0次

    JAVA SELECTOR

    Java NIO根据操作系统不同, 针对nio中的Selector有不同的实现
    java.nio.channels.spi.SelectorProvider

    /**
         * Returns the system-wide default selector provider for this invocation of
         * the Java virtual machine.
         *
         * <p> The first invocation of this method locates the default provider
         * object as follows: </p>
         *
         * <ol>
         *
         *   <li><p> If the system property
         *   <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is
         *   taken to be the fully-qualified name of a concrete provider class.
         *   The class is loaded and instantiated; if this process fails then an
         *   unspecified error is thrown.  </p></li>
         *
         *   <li><p> If a provider class has been installed in a jar file that is
         *   visible to the system class loader, and that jar file contains a
         *   provider-configuration file named
         *   <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource
         *   directory <tt>META-INF/services</tt>, then the first class name
         *   specified in that file is taken.  The class is loaded and
         *   instantiated; if this process fails then an unspecified error is
         *   thrown.  </p></li>
         *
         *   <li><p> Finally, if no provider has been specified by any of the above
         *   means then the system-default provider class is instantiated and the
         *   result is returned.  </p></li>
         *
         * </ol>
         *
         * <p> Subsequent invocations of this method return the provider that was
         * returned by the first invocation.  </p>
         *
         * @return  The system-wide default selector provider
         */
        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;
                            }
                        });
            }
        }
    
    
    

    DefaultSelectorProvider

    根据系统不同编译的二进制JDK不同

    • mac
    
    public class DefaultSelectorProvider {
    
        /**
         * Prevent instantiation.
         */
        private DefaultSelectorProvider() { }
    
        /**
         * Returns the default SelectorProvider.
         */
        public static SelectorProvider create() {
            return new sun.nio.ch.KQueueSelectorProvider();
        }
    
    }
    
    • solaris
     /**
         * Returns the default SelectorProvider.
         */
        public static SelectorProvider create() {
            String osname = AccessController
                .doPrivileged(new GetPropertyAction("os.name"));
            if (osname.equals("SunOS"))
                return createProvider("sun.nio.ch.DevPollSelectorProvider");
            if (osname.equals("Linux"))
                return createProvider("sun.nio.ch.EPollSelectorProvider");
            return new sun.nio.ch.PollSelectorProvider();
        }
    
    • windows
     /**
         * Returns the default SelectorProvider.
         */
        public static SelectorProvider create() {
            return new sun.nio.ch.WindowsSelectorProvider();
        }
    

    以上是不同操作系统的默认实现,用户可以指定不同的selector实现

    • 指定系统变量
     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);
            }
        }
    
    
    Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider
    
    • SPI
    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;
                }
            }
        }
    

    JDK NIO 在linux 平台默认使用epoll方式, 为什么netty还要提供一个基于epoll的实现?

    NETTY作者回答

    https://stackoverflow.com/questions/23465401/why-native-epoll-support-is-introduced-in-netty

    • Netty的 epoll transport使用 epoll edge-triggered 而 java的 nio 使用 level-triggered.
    • 另外netty epoll transport 暴露了更多的nio没有的配置参数, 如 TCP_CORK, SO_REUSEADDR等等

    netty 作者博客

    http://normanmaurer.me/

    相关文章

      网友评论

          本文标题:JAVA NIO SELECTOR

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