借鉴于: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. 【HAOI2010】订货
  2. BeautifulSoup_第二节
  3. 最短路径(Dijkstra算法)(c/c++)
  4. 消除python变量的值_SPSS变量值标签的批量设置、复制、显示及删除问题
  5. 如何提高gps精度_如何在锻炼应用程序中提高GPS跟踪精度
  6. mysql定义条件和处理_mysql sql存储过程条件定义与处理
  7. 怎么查看这个docker 有没有 restart 属性_感受 Docker 魅力, 排解决多应用部署之疼,Docker Compose + Spring Boot 实践...
  8. 【Go】高性能的简繁体转换
  9. 大学计算机ps教程 pdf,Photoshop中文教程.pdf
  10. Chrom安装Axure插件浏览原型图
  11. 基于JAVA超市商品管理系统计算机毕业设计源码+系统+lw文档+部署
  12. 百度AI图像处理—图像主体识别调用教程(基于Python3-附Demo)
  13. android版本高低有啥好处与不好,WP跟安卓比流畅 但为什么就不好用呢?
  14. IOS superView和subView
  15. Excel 经纬度互相转换
  16. java读取文本文件,并且去除重复字段
  17. spyder的安装配置及无法使用第三方包的问题
  18. 怎么建立软连接和删除软连接、宏定义个声明一年有多少秒、关于自定义函数类型指针
  19. 谁来买我们的DRAM?美光公司摸摸干瘪的口袋
  20. 如何启用计算机睡眠功能,如何让电脑休眠_如何开启电脑休眠模式-win7之家

热门文章

  1. [整理]svn commit obstructed
  2. VS2015报错C4996处理
  3. PartNet: A Recursive Part Decomposition Network for Fine-grained and Hierarchical Shape Segmentation
  4. Mysql tinyint(1)与tinyint(4)的区别
  5. position:fixed;
  6. 【大数据分析】未开先火|北京环球影城网络传播热度洞察
  7. matlab高程数据点,matlab 对tif数据高程图的处理分析
  8. 一个业务型算法工程师的技能清单
  9. thinkPHP中的控制器与视图层
  10. API数据接口该怎么对接