Java-NIO之Selector创建过程详解

 

 前言

  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 PrivilegedActionSelectorProvider() {

  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。

  


转载于:https://juejin.im/post/5be401046fb9a049f153b0b0

你可能感兴趣的:(Java-NIO之Selector创建过程详解)