资讯专栏INFORMATION COLUMN

【源码阅读】Java-NIO之Selector创建过程详解

187J3X1 / 920人阅读

摘要:好了,目前还不难,我们起码知道这个抽象类上面的部分关系,因此当然也有自己的方法,如下。又来一个的供应商好吧,大佬们总是喜欢用一些设计模式的东西,没错,也是一个抽象类,这个现在不用太在意了。

前言

java nio,一个入门netty之前需要了解下的非阻塞I/O实现,传统的Socket通信,启动监听后accept会一直处于阻塞状态,那么如果你想要多个(并发)通信时,那么我们就需要多个线性去执行,而且还会存在一些无用线程占用我们的资源。

nio的Selector很好的解决了这个问题,它可以仅仅通过一个线程去跑多个连接,每个连接没有资格去占用自己的线程,而是由Selector去分发。接下来让我们一起来了解下作者的设计实现思路吧。

我也不是大神,大家有观点也可以提出来。

启动Selector

使用过NIO的朋友都知道,要用就要先启动Selector。

Selector selector = Selector.open();

没错,这样一个非阻塞的功能就已经开始运行了,使用时间通知API以确定在一组非阻塞套接字中,哪些已经就绪能够进行I/O相关的操作。

即一个单一线程处理多个并发的连接

源码阅读

首先我们看看Selector这个类,它是一个抽象类,并没有写什么具体实现,毕竟是Mark Reinhold写的,怎么可能那么快就让你们看到实在的东西呢?

public abstract class Selector implements Closeable{}

现在起码我们知道这个抽象类里面起码open这个静态方法,Selector还实现了Closeable接口,Closeable是java.io的一个关闭接口,它本身也继承了java.lang的AutoCloseable。

public interface Closeable extends AutoCloseable{
    public void close() throws IOException;
}

public interface AutoCloseable{
    void close() throws Exception;
}

好了,目前还不难,我们起码知道Selector这个抽象类上面的部分关系,因此Selector当然也有自己的close方法,如下。

public abstract class Selector implements Closeable {

    //....

    public abstract void close() throws IOException;

}
open方法

接下来才是重头戏啦,open方法究竟做了啥,让通信连接在一个线程就可以完好的处理,它就行启动了什么大Boss。我有点喜欢这个作者了,他又一次让我打开另一扇门。

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

又来一个SelectorProvider?

Selector的供应商?好吧,大佬们总是喜欢用一些设计模式的东西,没错,SelectorProvider也是一个抽象类,这个现在不用太在意了。

SelectorProvider的构造方法,emmmm,大家看看就好

protected SelectorProvider() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPermission(new RuntimePermission("selectorProvider"));
}

SecurityManager(类似java安全的东西)、RuntimePermission(类似java权限的东西),大致就是非常安全的创建一个SelectorProvider。

回到原文,open方法调用了返回了一个Selector,是由SelectorProvider调用provider方法再调用openSelector而得到的。

provider方法

我们再看看provider方法吧,我都快急死了。一进来就看到synchronized!额,线程锁,保证线程安全的东西,我们理解主要的先,内容是这样的。

public static SelectorProvider provider() {
    synchronized (lock) {
        if (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();
                return provider;
            }
        });
    }
}

哇,又来。首先就容量理解啦,provider不为空就直接返回,这个provider是SelectorProvider本身的一个静态成员

private static SelectorProvider provider = null;

当然第一次的时候一定是null的,然后就执行下面的方法,反正就是去判断几种情况后返回一个provider。创建时用到了java反射机制哦,有兴趣的朋友去看看。

那么起码我们知道他也是判断情况后返回SelectorProvider。

openSelector方法
public abstract AbstractSelector openSelector()
        throws IOException;

浅显易懂,返回一个新的selector

没错,一个简单的open就是告诉你,你需要通过调用SelectorProvider的方法来生成系统默认SelectorProvider并返回一个okay的Selector。

结尾

emmmm,好像没有真正的了解到如何通过一个线程来实现分发多个连接,不过不要紧,这么牛逼的NIO怎么可能一篇小文章就能说明白的?

下节继续......

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76768.html

相关文章

  • Netty 源码分析 三 我就是大名鼎鼎的 EventLoop(一)

    摘要:目录源码之下无秘密做最好的源码分析教程源码分析之番外篇的前生今世的前生今世之一简介的前生今世之二小结的前生今世之三详解的前生今世之四详解源码分析之零磨刀不误砍柴工源码分析环境搭建源码分析之一揭开神秘的红盖头源码分析之一揭开神秘的红盖头客户端 目录 源码之下无秘密 ── 做最好的 Netty 源码分析教程 Netty 源码分析之 番外篇 Java NIO 的前生今世 Java NI...

    livem 评论0 收藏0
  • #yyds干货盘点# Netty源码分析Reactor线程模型详解

    摘要:启动然后一路执行到方法中,调用方法启动线程。的执行流程中的方法是一个无限循环的线程,在该循环中主要做三件事情,如图所示。而这个唤醒是没有任何读写请求的,从而导致线程在做无效的轮询,使得占用率较高。 上一篇文章,分析了Netty服务端启动的初始化过程,今天我们来分析一下Netty中的Reactor线程模型在分析源...

    番茄西红柿 评论0 收藏2637
  • Netty 源码分析 一 揭开 Bootstrap 神秘的红盖头 (服务器端)

    摘要:目录源码分析之番外篇的前生今世的前生今世之一简介的前生今世之二小结的前生今世之三详解的前生今世之四详解源码分析之零磨刀不误砍柴工源码分析环境搭建源码分析之一揭开神秘的红盖头源码分析之一揭开神秘的红盖头客户端源码分析之一揭开神秘的红盖头服务器 目录 Netty 源码分析之 番外篇 Java NIO 的前生今世 Java NIO 的前生今世 之一 简介 Java NIO 的前生今世 ...

    张金宝 评论0 收藏0
  • Netty 源码分析 二 贯穿Netty 的大动脉 ── ChannelPipeline (一)

    摘要:目录源码之下无秘密做最好的源码分析教程源码分析之番外篇的前生今世的前生今世之一简介的前生今世之二小结的前生今世之三详解的前生今世之四详解源码分析之零磨刀不误砍柴工源码分析环境搭建源码分析之一揭开神秘的红盖头源码分析之一揭开神秘的红盖头客户端 目录 源码之下无秘密 ── 做最好的 Netty 源码分析教程 Netty 源码分析之 番外篇 Java NIO 的前生今世 Java NI...

    tunny 评论0 收藏0
  • 读Zepto源码Selector模块

    摘要:如果伪类的参数不可以用转换,则参数为字符串,用正则将字符串前后的或去掉,再赋值给最后执行回调,将解释出来的参数传入回调函数中,将执行结果返回。重写的方法,改过的调用的是方法,在回调函数中处理大部分逻辑。 Selector 模块是对 Zepto 选择器的扩展,使得 Zepto 选择器也可以支持部分 CSS3 选择器和 eq 等 Zepto 定义的选择器。 在阅读本篇文章之前,最好先阅读《...

    Jioby 评论0 收藏0

发表评论

0条评论

187J3X1

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<