上面测试论证系统内核在read data时会阻塞,如果我们在把第一个阶段解决掉那么性能就会提高

NIO 编程
JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度。实际上,“旧”的I/O包已经使用NIO重新实现过,即使我们不显式的使用NIO编程,也能从中受益。速度的提高在文件I/O和网络I/O中都可能会发生,但本文只讨论后者。
NIO 简介
NIO我们一般认为是New I/O(也是官方的叫法),因为它是相对于老的I/O类库新增的(其实在JDK 1.4中就已经被引入了,但这个名词还会继续用很久,即使它们在现在看来已经是“旧”的了,所以也提示我们在命名时,需要好好考虑),做了很大的改变。但民间跟多人称之为Non-block I/O,即非阻塞I/O,因为这样叫,更能体现它的特点。而下文中的NIO,不是指整个新的I/O库,而是非阻塞I/O。
NIO提供了与传统BIO模型中的Socket和ServerSocket相对应的SocketChannel和ServerSocketChannel两种不同的套接字通道实现。
新增的着两种通道都支持阻塞和非阻塞两种模式。

由于sun公司出技术要考虑兼容历史问题,所以新的NIO操作添加新的对象,其中比较重要的对象

1.Channel 通道

2.Buffer 缓冲区

3.Selector 多路复用器

4.SelectionKey op key

下面会先对基础知识进行介绍。

1.通道 Channel
我们对数据的读取和写入要通过Channel,它就像水管一样,是一个通道。通道不同于流的地方就是通道是双向的,可以用于读、写和同时读写操作。
底层的操作系统的通道一般都是全双工的,所以全双工的Channel比流能更好的映射底层操作系统的API。而装载数据对象为Buffer
Channel主要分两大类:
SelectableChannel:用户网络读写
FileChannel:用于文件操作

2、缓冲区 Buffer
Buffer是一个对象,包含一些要写入或者读出的数据。
在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。
缓冲区实际上是一个数组,并提供了对数据结构化访问以及维护读写位置等信息。
具体的缓存区有这些:ByteBuffe、CharBuffer、 ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer。他们实现了相同的接口:Buffer。

我们只关心ByteBuffe即可

3、多路复用器 Selector
Selector是Java NIO 编程的基础。
Selector提供选择已经就绪的任务的能力:Selector会不断轮询注册在其上的Channel,如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来,然后通过SelectionKey可以获取就绪Channel的集合,进行后续的I/O操作。
一个Selector可以同时轮询多个Channel,因为JDK使用了epoll()代替传统的select实现,所以没有最大连接句柄1024/2048的限制。所以,只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。

4、op key SelectionKey

SelectionKey 是socket操作集合,有OP_ACCEPT 接收新的socket连接,OP_CONNECT 客户端连接操作,OP_WRITE 数据写入系统操作,OP_READ 数据准备好

要注意的是:由于SelectionKey 状态是叠加的,通过Selector定时轮询,会积累多个SelectionKey同多个op key,所以会返回 Set<SelectionKey> 集合,

当操作完后要删除注册的SelectionKey或清掉状态,这点比较麻烦要开发者自行管理,不太人性

而返回多个SelectionKey应用层不知道是那个socket来源,所以在OP_ACCEPT同OP_CONNECT 操作时就要调用 attach方法绑定标识,而里面用到黑科技 AtomicReferenceFieldUpdater 感兴趣读者可以看下源码

小结:通过对象定义跟职责,我们大概组合下如果工作的

1.能过Selector定时轮询,返回 Set<SelectionKey> 进行分发处理

2.遍历Set<SelectionKey> 按不同 op key 切分不同handler 分而治之

3.绑定socet标识,方便提取上下文

4.处理完成后要向集合 移除 SelectionKey同清理状态

5.读写数据 channel 通过Buffer处理

nonblocking I/O 非阻塞模型:如前端比较熟悉的技术ajax轮询

I/O multiplexing (select and poll) IO多路复用模型:select先阻塞,有活动套接字才返回。与blocking I/O相比,select会有两次系统调用,但是select能处理多个套接字。

由于每个对象学习成本较大,加上需要相应的工作经验,估计要三四年网络开发编程经验,还有个比较恶心的地方jdk nio有BUG的,以后再介绍。

了解这些技术起码知道有那些坑,实际使用时能避免出现,解决一个问题时要选择最优方案。

选择netty框架是种不错的选择,毕竟不是每个人都有能力同充足时间开发的。

[编织消息框架][网络IO模型]NIO(select and poll)的更多相关文章

  1. [编织消息框架][网络IO模型]BIO

    既然跟网络内容有关就不得不学习网络IO模型,时代在进步,技术也在进步,采取使用那种网络IO模型就已经确定应用程序规模 阻塞IO(blocking IO) 在linux中,默认情况下所有的socket都 ...

  2. [编织消息框架][网络IO模型]aio

    asynchronous I/O (the POSIX aio_functions)—————异步IO模型最大的特点是 完成后发回通知. [编织消息框架][网络IO模型]NIO(select and ...

  3. [编织消息框架][网络IO模型]Netty Reactor

    严格来讲Netty Reactor是一种设计模式,一听模式两字就知道了吧,套路哈哈 Reactor中文译为“反应堆”. 看图netty处理流程 1.netty server 至少有两组reactor. ...

  4. 五种网络IO模型以及多路复用IO中select/epoll对比

    下面都是以网络读数据为例 [2阶段网络IO] 第一阶段:等待数据 wait for data 第二阶段:从内核复制数据到用户 copy data from kernel to user 下面是5种网络 ...

  5.  打开APP  04 | 网络通信:RPC框架在网络通信上更倾向于哪种网络IO模型? 2020-02-26 何小锋

     打开APP  04 | 网络通信:RPC框架在网络通信上更倾向于哪种网络IO模型? 2020-02-26 何小锋

  6. Socket-IO 系列(一)Linux 网络 IO 模型

    Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...

  7. 通过实例理解Java网络IO模型

    网络IO模型及分类 网络IO模型是一个经常被提到的问题,不同的书或者博客说法可能都不一样,所以没必要死抠字眼,关键在于理解. Socket连接 不管是什么模型,所使用的socket连接都是一样的. 以 ...

  8. 网络IO模型与Reactor模式

    一.三种网络IO模型: 分类: BIO 同步的.阻塞式 IO NIO 同步的.非阻塞式 IO AIO 异步非阻塞式 IO 阻塞和同步的概念: 阻塞:若读写未完成,调用读写的线程一直等待 非阻塞:若读写 ...

  9. python网络编程——网络IO模型

    1 网络IO模型介绍 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:    (1)同步阻塞IO(Blocking IO):即传统的IO模型.    (2)同步非阻塞IO(Non-bl ...

随机推荐

  1. Sublime text3 代码格式化插件

    使用 Sublime text 3 格式化HTML代码,需要安装插件,具体安装步骤如下: 1. 打开菜单 -> 首选项(Perferences) -> 插件控制(Packpage Cont ...

  2. 实践作业2:黑盒测试实践——小组任务分工 Day 1

    今日教学实验任务分配后,课下小组例会完成任务分工,具体分工如下: (1)系统需求分析--刘思佳 (2)设计测试用例--王俊杰 (3)编写.运行测试脚本--郜昌磊 (4)记录测试过程--吴慧杰 (5)记 ...

  3. PHP 八种基本的数据类型小结

    四种标量类型: boolean (布尔型) integer (整型) float (浮点型, 也称作 double) string (字符串) 两种复合类型: array (数组) object (对 ...

  4. 如何编写一个稳定的网络程序(TCP)

    本节我们看一下怎样才能编写一个基于TCP稳定的客户端或者服务器程序,主要以试验抓包的方式观察数据包的变化,对网络中出现的多种情况进行分析,分析网络程序中常用的技术及它们出现的原因,在之后的编程中能早一 ...

  5. huangwenlong and hanqihong开光的dijkstra

    #include<iostream> #include<vector> #include<queue> #include<cstring> #inclu ...

  6. System.ServiceModel.CommunicationException: 已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性。

  7. 基于 HTML5 Canvas 的 3D 压力器反序列化

    在实际应用中,我觉得能够通过操作 JSON 文件来操作 3D 上的场景变化是非常方便的一件事,尤其是在做编辑器进行拖拽图元并且在图元上产生的一系列变化的时候,都能将数据很直观地反应给我们,这边我们简单 ...

  8. 大白话Vue源码系列(03):生成AST

    阅读目录 AST 节点定义 标签的正则匹配 解析用到的工具方法 解析开始标签 解析结束标签 解析文本 解析整块 HTML 模板 未提及的细节 本篇探讨 Vue 根据 html 模板片段构建出 AST ...

  9. PHP开发中需要注意几点事项,新手少走弯路必备知识

    这篇文章主要介绍了PHP开发需要注意的几点事项总结,非常详细,需要的朋友可以参考下.新手多看看避免走弯路. 1.使用内嵌的HTML代码,而不是PHP的echo语句. 因为PHP是一门嵌入式Web编程语 ...

  10. Ubuntu下deb包的解压、打包、安装、卸载及常用命令参数

    1.首先下载deb包,比如:将其放在 /home/tools/ 根目录下: 2.进入到tools根目录下的终端,输入下面命令创建文件夹extract,并在extract文件夹下创建DEBIAN文件夹 ...