昨天我们介绍了一下SelectorProvider和IO multiplexing.特别是IO multiplexing中的epoll系统调用,是Linux版本的Java的NIO的核心实现.

那今天我们就来介绍一下, Java NIO中的核心组件, Selector和Channel.这两个组件,对于熟悉Java OIO,而不熟悉Java NIO的朋友来说,理解其作用是极其不易的.

前提条件

在阅读这篇文章之前,如果各位不熟悉甚至没有听说过IO multiplexing中的epoll,请务必花时间去了解一下.了解了它们之后,就很容易理解Java NIO的实现了.

这里我们讲解的是Linux版本且内核版本大于2.6的Java NIO的实现,对于其他的系统或者内核版本较低的Java NIO,其具体实现是不一样的.

举例来说, Linux 内核版本大于等于2.6的Java NIO是采用epoll来实现的.而Linux内核版本小于2.6的Java NIO,则是采用poll来实现的.

Selector和Channel

Selector和Channel的关系,如下图所示:

各位如果了解过epoll的话,应该知道epoll_create操作会创建一个需要被监听的file descriptor.然后,epoll_ctl操作会为告诉内核,需要监听一个file descripitor的什么事件.最后,使用epoll_wait来告诉内核开始监听.

这里我们就可以把Selector比作epoll中的内核.把Channel比作epoll_create操作创建的file descriptor.这样就很容易理解了吧.

因为Java NIO实际上是给我们对IO multiplexing进行了封装,隐藏了其底层的实现.所以我们完全可以这样来理解.

贴出在Java NIO tutorial中看到的一个图片,

对于这张图片,我实在是不能苟同其说法.我们可以看到,在这张图片中,我们可以看到,一个线程中只有一个Selector,每个Selector负责监控三个Channel.而实际上,一个线程中,并不是必须只能有一个Selector.一个Selector也不是只能注册三个Channel.

在AbstractSelector的源码中,我们可以看到,实际上它只维护了一个不再监听的Channel的集合:

我们查看具体的Selector的父类,SelectorImpl,中的register方法的实现.跟具体的Selector实现相关的类,在JDK提供的src.zip源码包中是找不到的.这里使用CFR反编译器反编译rt.jar包.从中找到其实现.

我们可以看到,它会把Channel进一步封装成SelectionKeyImpl.然后使用implRegister方法来实现具体的注册过程.从SelectorImpl的源码中,我们同样可以看到,implRegister方法是一个抽象方法,需要其子类来实现具体的注册过程.

这里我们感兴趣的子类是EPollSelectorImpl,我们查看其源码,可以看到其中维护了一个从file descriptor到SelectionKeyImpl的Map.我们刚刚也提到了,SelectionKeyImpl中,包装了一个Channel,

我们从EPollSelectorImpl的implRegister方法中,也没有看到会对Map这个表示EPollSelectorImpl维护的Channel的Map进行尺寸限制的操作.即并没有限制一个EPollSelectorImpl可以注册的Channel的数量.

反而是在Channel中,维护了它向Selector注册时,Selector给其返回的SelectionKey的集合.相当于维护了它已经注册的Selector的集合.

我们查看AbstractSelectableChannel的向Selector注册的源码:

我们可以看到,它会把Selector给它返回的SelectionKey加入到上面我们说过的那个集合中,我们看看addKey()方法的具体实现:

在这里我们就可以看到,默认情况下,Channel会创建一个容量为3的表示它注册的Selector的集合.当它需要向更多的Selector注册时,则对这个集合进行扩容.

而并没有提到一个Selector中最多可以注册多少个Channel.

java selector 源码_Java NIO核心组件-Selector和Channel相关推荐

  1. java selector 源码_Java NIO——Selector机制源码分析---转

    一直不明白pipe是如何唤醒selector的,所以又去看了jdk的源码(openjdk下载),整理了如下: 以Java nio自带demo : OperationServer.java   Oper ...

  2. java商城源码_java 多商户商城系统源码分享

    三勾商城多商户是开发友好的微信小程序商城,框架支持SAAS,支持发布 iOS + Android + 公众号 + H5 + 各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)等多个平台,不可多得 ...

  3. java验证码源码_Java通用验证码程序及应用示例(提供源码下载)

    评论 # re: Java通用验证码程序及应用示例(提供源码下载) 2009-11-27 17:09 零全零美 多谢博主写出这么好的总结,如果能加上汉字验证码,会更完美!  回复  更多评论 # re ...

  4. java hashset 源码_Java集合源码分析-HashSet和LinkedHashSet

    前两篇文章分别分析了Java的ArrayList和LinkedList实现原理,这篇文章分析下HashSet和LinkedHashSet的源码.重点讲解HashSet,因为LinkedHashSet是 ...

  5. java linkedlist源码_Java集合之LinkedList源码分析

    一.LinkedList简介 LinkedList是一种可以在任何位置进行高效地插入和移除操作的有序序列,它是基于双向链表实现的. ps:这里有一个问题,就是关于实现LinkedList的数据结构是否 ...

  6. java queue源码_java源码解读--queue

    queue接口特点:可以模拟队列行为,即"先进先出". 接口结构 queue接口继承了Collection接口,并增加了一些新方法 1 2 3 4 5 6 7 8 9 10 11 ...

  7. java join 源码_java并发:join源码分析

    join join join是Thread方法,它的作用是A线程中子线程B在运行之后调用了B.join(),A线程会阻塞直至B线程执行结束 join源码(只有继承Thread类才能使用) 基于open ...

  8. java地图源码_Java集合源码分析(四)HashMap

    一.HashMap简介 1.1.HashMap概述 HashMap是基于哈希表的Map接口实现的,它存储的是内容是键值对映射.此类不保证映射的顺序,假定哈希函数将元素适当的分布在各桶之间,可为基本操作 ...

  9. java 数组 源码_Java数组转List的三种方式及对比

    来源:https://s.yam.com/6wu6n 前言: 本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析. 一.最常见方式(未必最佳 ...

最新文章

  1. 微软收购 GitHub 两年后,大咖共论开源新生态
  2. 《30天吃掉那只 TensorFlow2.0 》(附下载)
  3. 非营利组织Eatbch展示了每一个小的微交易是如何起作用的
  4. cgicc thttpd经常用的调试命令
  5. Node.js之readline模块的使用
  6. mdAAPP:安装后会一直存在手机中,安装数据及缓存都会占用大量内存,而且各家全家桶APP之间都有一些藕断丝连的唤醒关系。 小程序:不需要安装在手机上,微信有严格的小程序内存管理机制,和微信共用内存使
  7. 为什么我会在2012年的新企业Java项目中使用Java EE而不是Spring
  8. QLive EULA
  9. 代码编辑器VS Code的“Chromium”版来啦:安全、开源、保护你的隐私
  10. Light oj 1233 - Coin Change (III) (背包优化)
  11. JavaScript Window Navigator
  12. 【TSP】基于matlab遗传算法求解30城市旅行商问题【含Matlab源码 135期】
  13. HDU 6188:Duizi and Shunzi(贪心)(广西邀请赛)
  14. MYSQL时间函数之FROM_UNIXTIME
  15. Android控件-TabLayout使用介绍
  16. Unity学习笔记(一)—— 基础知识
  17. CISCO 6509 三层交换机配置
  18. Mind Map - FreeMind
  19. 不学好数学也想当数据科学家?不存在的
  20. 视频跟踪——TLD算法

热门文章

  1. mysql部门人员排序设计_MySQL数据库访问性能优化
  2. python 3d重建_3D点云重建原理及Pytorch实现
  3. python发送邮箱_你知道怎么用Python发送邮件吗?
  4. 利用python处理中国地面气候资料日值数据集(V3.0)
  5. 【转】.NET平台开发Mongo基础知识
  6. 【转】一个ASP.NET MVC中ajax调用WebApi返回500 Internal Server Error的调错方法。
  7. iis到w3wp的数据流及工作原理
  8. 软件测试计划时要记住什么
  9. 【编译原理】词法分析程序设计
  10. REVERSE-PRACTICE-BUUCTF-1