java NIO BIO和AIO
借鉴于: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相关推荐
- java nio oio_NIO,OIO,AIO区别
OIO中,每个线程只能处理一个channel(同步的,该线程和该channel绑定). 线程发起IO请求,不管内核是否准备好IO操作,从发起请求起,线程一直阻塞,直到操作完成,如图: NIO中,每个线 ...
- 常见的 IO 模型有哪些?Java 中 BIO、NIO、AIO 的区别?
IO 模型这块确实挺难理解的,需要太多计算机底层知识.写这篇文章用了挺久,就非常希望能把我所知道的讲出来吧!希望朋友们能有收货!为了写这篇文章,还翻看了一下<UNIX 网络编程>这本书,太 ...
- JAVA 中BIO,NIO,AIO的理解
[转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...
- java mysql aio_Java中的NIO,BIO,AIO分别是什么
Java中的NIO,BIO,AIO分别是什么 BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开 ...
- bio linux 创建_不断升级,Java之BIO、NIO、AIO的演变
一.前言 一句话概括BIO NIO AIO: 第一阶段,服务端采用同步阻塞的BIO: 第二阶段,服务端采用同步阻塞的线程池的BIO: 第三阶段,JDK4之后服务端采用同步非阻塞的NIO: 第四阶段,J ...
- 谈谈java的bio、nio、aio模型
目录 socket IO(BIO)和NIO的区别 同步和异步 bio:同步阻塞式IO NIO:同步非阻塞IO(工作中用的很少) Buffer使用 NIO代码 AIO socket Socket又称&q ...
- Java IO模型--BIO、NIO Single Thread、NIO Reactor、AIO单线程及多线程AIO
目录 BIO server端: client端: NIO 单线程模型 Reactor模型 代码实现 AIO 单线程AIO代码实现 线程池AIO代码实现 BIO 当确定客户端连接数很少时,BIO也可以使 ...
- Java IO(BIO, NIO, AIO) 总结
文章转载自:JavaGuide 目录 BIO,NIO,AIO 总结 同步与异步 阻塞和非阻塞 1. BIO (Blocking I/O) 1.1 传统 BIO 1.2 伪异步 IO 1.3 代码示例 ...
- 【Java】BIO、NIO、AIO网络编程模型概述
前言 我们知道,UNIX环境下常见的网络I/O模型有5种: 同步阻塞 同步非阻塞 I/O复用 信号驱动 异步非阻塞 那么基于上述五种模型,Java中,随着NIO和AIO(NIO 2.0)的引入,一般具 ...
最新文章
- 【HAOI2010】订货
- BeautifulSoup_第二节
- 最短路径(Dijkstra算法)(c/c++)
- 消除python变量的值_SPSS变量值标签的批量设置、复制、显示及删除问题
- 如何提高gps精度_如何在锻炼应用程序中提高GPS跟踪精度
- mysql定义条件和处理_mysql sql存储过程条件定义与处理
- 怎么查看这个docker 有没有 restart 属性_感受 Docker 魅力, 排解决多应用部署之疼,Docker Compose + Spring Boot 实践...
- 【Go】高性能的简繁体转换
- 大学计算机ps教程 pdf,Photoshop中文教程.pdf
- Chrom安装Axure插件浏览原型图
- 基于JAVA超市商品管理系统计算机毕业设计源码+系统+lw文档+部署
- 百度AI图像处理—图像主体识别调用教程(基于Python3-附Demo)
- android版本高低有啥好处与不好,WP跟安卓比流畅 但为什么就不好用呢?
- IOS superView和subView
- Excel 经纬度互相转换
- java读取文本文件,并且去除重复字段
- spyder的安装配置及无法使用第三方包的问题
- 怎么建立软连接和删除软连接、宏定义个声明一年有多少秒、关于自定义函数类型指针
- 谁来买我们的DRAM?美光公司摸摸干瘪的口袋
- 如何启用计算机睡眠功能,如何让电脑休眠_如何开启电脑休眠模式-win7之家
热门文章
- [整理]svn commit obstructed
- VS2015报错C4996处理
- PartNet: A Recursive Part Decomposition Network for Fine-grained and Hierarchical Shape Segmentation
- Mysql tinyint(1)与tinyint(4)的区别
- position:fixed;
- 【大数据分析】未开先火|北京环球影城网络传播热度洞察
- matlab高程数据点,matlab 对tif数据高程图的处理分析
- 一个业务型算法工程师的技能清单
- thinkPHP中的控制器与视图层
- API数据接口该怎么对接