借鉴于:https://zhuanlan.zhihu.com/p/23488863

NIO:NEW IO或not blocking IO,非阻塞的io模型,也是i/o多路复用的基础;

传统的io为bio(blocking i/o),阻塞io;使用bio的经典方式如下:

{

ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//线程池

ServerSocket serverSocket = new ServerSocket();

serverSocket.bind(8088);

while(!Thread.currentThread.isInturrupted()){//主线程死循环等待新连接到来

Socket socket = serverSocket.accept();

executor.submit(new ConnectIOnHandler(socket));//为新的连接创建新的线程

}

class ConnectIOnHandler extends Thread{

private Socket socket;

public ConnectIOnHandler(Socket socket){

this.socket = socket;

}

public void run(){

while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循环处理读写事件

String someThing = socket.read()....//读取数据

if(someThing!=null){

......//处理数据

socket.write()....//写数据

}

}

}

}

经典的每连接每线程的模型,之所以使用多线程,主要原因在于socket.accept()、socket.read()、socket.write()三个主要函数都是同步阻塞的,当一个连接在处理I/O的时候,系统是阻塞的,如果是单线程的话必然就挂死在那里;但CPU是被释放出来的,开启多线程,就可以让CPU去处理更多的事情。其实这也是所有使用多线程的本质:

1)利用多核。

2)当I/O阻塞系统,但CPU空闲的时候,可以利用多线程使用CPU资源。

现在的多线程一般都使用线程池,可以让线程的创建和回收成本相对较低。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的I/O并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。

不过,这个模型最本质的问题在于,严重依赖于线程。但线程是很"贵"的资源,主要表现在:

a线程的创建和销毁成本很高,在Linux这样的操作系统中,线程本质上就是一个进程。创建和销毁都是重量级的系统函数。

b线程本身占用较大内存,像Java的线程栈,一般至少分配512K~1M的空间,如果系统中的线程数过千,恐怕整个JVM的内存都会被吃掉一半。

c线程的切换成本是很高的。操作系统发生线程切换的时候,需要保留线程的上下文,然后执行系统调用。如果线程数过高,可能执行线程切换的时间甚至会大于线程执行的时间,这时候带来的表现往往是系统load偏高、CPU sy使用率特别高(超过20%以上),导致系统几乎陷入不可用的状态。

d容易造成锯齿状的系统负载。因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。

所以,当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。随着移动端应用的兴起和各种网络游戏的盛行,百万级长连接日趋普遍,此时,必然需要一种更高效的I/O处理模型。

所以出现了not blocking i/o用于解决上面的问题

Nio特点:socket主要的读写注册和接收函数,在等待阶段都是非阻塞的,真正的I/O操作同步阻塞的.

BIO\NIO\AIO的比较:

所有的系统I/O分为两个部分:等待就绪和操作.如读函数,分为等待系统可读和真正的读;但等待就绪不使用CPU,但真正的读写操作的是使用cpu的,当然操作执行期间也是一种阻塞.

以socket.read()为例:

对于BIO:socket,read()时,如果TCP RecvBuffer里面没有数据,函数会一直阻塞,直到收到数据,返回读到的数据.

NIO:如果TCP RecvBuffer里面没有数据,则直接返回0,永远不会阻塞;如果有数据,则直接把数据从网卡读到内存,此时进程需要间断查询数据是否已经读完..

AIO:不但等待就绪是非阻塞的,就连数据从网卡读到内存的过程也是异步的,此时不再需要进程去查询是否已经读完,而是直接可以干别的事,数据已经读完时会主动告知进程

对NIO的使用:

NIO的读写函数可以立刻返回,这就给了我们不开线程利用CPU的最好机会:如果一个连接不能读写(socket.read()返回0或者socket.write()返回0),我们可以把这件事记下来,记录的方式通常是在Selector上注册标记位,然后切换到其它就绪的连接(channel)继续进行读写。

interface ChannelHandler{

void channelReadable(Channel channel);

void channelWritable(Channel channel);

}

class Channel{

Socket socket;

Event event;//读,写或者连接

}

//IO线程主循环:

class IoThread extends Thread{

public void run(){

Channel channel;

while(channel=Selector.select()){//选择就绪的事件和对应的连接

if(channel.event==accept){

registerNewChannelHandler(channel);//如果是新连接,则注册一个新的读写处理器

}

if(channel.event==write){

getChannelHandler(channel).channelWritable(channel);//如果可以写,则执行写事件

}

if(channel.event==read){

getChannelHandler(channel).channelReadable(channel);//如果可以读,则执行读事件

}

}

}

Map<Channel,ChannelHandler> handlerMap;//所有channel的对应事件处理器

}

这个程序很简短,也是最简单的Reactor模式:注册所有感兴趣的事件处理器,单线程轮询选择就绪事件,执行事件处理器。

借鉴于:https://zhuanlan.zhihu.com/p/23488863

java NIO BIO和AIO相关推荐

  1. java nio oio_NIO,OIO,AIO区别

    OIO中,每个线程只能处理一个channel(同步的,该线程和该channel绑定). 线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成,如图: NIO中,每个线 ...

  2. 常见的 IO 模型有哪些?Java 中 BIO、NIO、AIO 的区别?

    IO 模型这块确实挺难理解的,需要太多计算机底层知识.写这篇文章用了挺久,就非常希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇文章,还翻看了一下<UNIX 网络编程>这本书,太 ...

  3. JAVA 中BIO,NIO,AIO的理解

    [转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...

  4. java mysql aio_Java中的NIO,BIO,AIO分别是什么

    Java中的NIO,BIO,AIO分别是什么 BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开 ...

  5. bio linux 创建_不断升级,Java之BIO、NIO、AIO的演变

    一.前言 一句话概括BIO NIO AIO: 第一阶段,服务端采用同步阻塞的BIO: 第二阶段,服务端采用同步阻塞的线程池的BIO: 第三阶段,JDK4之后服务端采用同步非阻塞的NIO: 第四阶段,J ...

  6. 谈谈java的bio、nio、aio模型

    目录 socket IO(BIO)和NIO的区别 同步和异步 bio:同步阻塞式IO NIO:同步非阻塞IO(工作中用的很少) Buffer使用 NIO代码 AIO socket Socket又称&q ...

  7. Java IO模型--BIO、NIO Single Thread、NIO Reactor、AIO单线程及多线程AIO

    目录 BIO server端: client端: NIO 单线程模型 Reactor模型 代码实现 AIO 单线程AIO代码实现 线程池AIO代码实现 BIO 当确定客户端连接数很少时,BIO也可以使 ...

  8. Java IO(BIO, NIO, AIO) 总结

    文章转载自:JavaGuide 目录 BIO,NIO,AIO 总结 同步与异步 阻塞和非阻塞 1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 ...

  9. 【Java】BIO、NIO、AIO网络编程模型概述

    前言 我们知道,UNIX环境下常见的网络I/O模型有5种: 同步阻塞 同步非阻塞 I/O复用 信号驱动 异步非阻塞 那么基于上述五种模型,Java中,随着NIO和AIO(NIO 2.0)的引入,一般具 ...

最新文章

  1. Java通过JDBC连接MySQL数据库
  2. 查看python安装路径以及pip安装的包
  3. easy_Maze 梅津美治郎 寒假逆向生涯(16/100)
  4. 文章章节序号编排常识
  5. P1060 开心的金明(01背包)
  6. Azure 国际版与中国版服务列表对(2020年6月版)
  7. 有限状态自动机java实现_用java开发编译器之:Thompson构造,将正则表达式转换为有限状态自动机...
  8. 028-Dell服务器做Raid
  9. Ubuntu IP设置为静态
  10. 语言怎么表示词谱_跨语言词表示方法(一)
  11. struts2的两个核心配置文件
  12. iOS webview 清除缓存
  13. 实现 int 类型(比如id)的模糊查询
  14. python自建模块_python导入自建模块的问题
  15. 戴尔Latitude5285笔记本触摸板失灵的原因
  16. 注意力机制论文:CCNet: Criss-Cross Attention for Semantic Segmentation及其PyTorch实现
  17. MapReduce----电信数据清洗
  18. linux 安装zh.utf 8,debian下安装locale并设置zh_CN.UTF-8
  19. Python 标准库之 Math 数学函数
  20. unity 之 Particle 二

热门文章

  1. 基于Socket、OpenCV和MFC实现的网络实时视频监控
  2. 2020年9月全国计算机二级c语言题库,2020年9月全国计算机等级考试二级C语言上机题库(共95套全)(76页)-原创力文档...
  3. 【NLP】1、nlp各类中文文本语料库
  4. Freemarker语法2
  5. ZYNQ开发系列——hw_platform包和BSP包中的一些理解
  6. 用邻接表dfs和bfs图
  7. 【转】常用的隧道技术
  8. 在线python编辑器-在线python编辑器
  9. win7 电脑如何内外网同时使用
  10. IDEA 注释模板,这样配置才够逼格!