8分钟深入浅出搞懂BIO、NIO、AIO
在高性能的IO体系设计中,BIO、NIO、AIO的概念,常常会让我们感到困惑不解。在Java面试中,我们也经常会被问到这个问题。譬如:
BIO、NIO、AIO 的概念同步/异步、阻塞/非阻塞的区别NIO 如何实现多路复用功能AIO、BIO、NIO的适用场景NIO的核心概念、应用和框架等等这块内容本身比较复杂,很难用三言两语说明白,而书上的定义不太容易理解。本篇内容按照我的理解,以尽可能简单、易懂的语言进行组织,希望能够帮助到大家快速理解这些概念。
AIO、BIO、NIO的区别
在弄清楚上面的几个问题之前,我们首先得明白什么是同步,异步,阻塞,非阻塞,只有这几个单个概念理解清楚了,然后在组合理解起来,就相对比较容易了。
IO模型主要分类:
同步(synchronous) IO和异步(asynchronous) IO阻塞(blocking) IO和非阻塞(non-blocking)IO同步阻塞(blocking-IO)简称BIO同步非阻塞(non-blocking-IO)简称NIO异步非阻塞(synchronous-non-blocking-IO)简称AIO1.BIO (同步阻塞I/O模式)
数据的读取写入必须阻塞在一个线程内等待其完成。
这里使用那个经典的烧开水例子,这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。
2.NIO(同步非阻塞)
同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。
3.AIO (异步非阻塞I/O模型)
异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。
4.IO与NIO区别
5.同步与异步的区别
同步发送一个请求,等待返回,再发送下一个请求,同步可以避免出现死锁,脏读的发生。
异步发送一个请求,不等待返回,随时可以再发送下一个请求,可以提高效率,保证并发。
6.阻塞和非阻塞
阻塞传统的IO流都是阻塞式的。也就是说,当一个线程调用read()或者write()方法时,该线程将被阻塞,直到有一些数据读读取或者被写入,在此期间,该线程不能执行其他任何任务。在完成网络通信进行IO操作时,由于线程会阻塞,所以服务器端必须为每个客户端都提供一个独立的线程进行处理,当服务器端需要处理大量的客户端时,性能急剧下降。
非阻塞JavaNIO是非阻塞式的。当线程从某通道进行读写数据时,若没有数据可用时,该线程会去执行其他任务。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以单独的线程可以管理多个输入和输出通道。因此NIO可以让服务器端使用一个或有限几个线程来同时处理连接到服务器端的所有客户端。
7.BIO、NIO、AIO适用场景
BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择。NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂。AIO方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。NIO的3个核心概念
NIO重点是把Channel(通道),Buffer(缓冲区),Selector(选择器)三个类之间的关系弄清楚。
1.缓冲区Buffer
Buffer是一个对象。它包含一些要写入或者读出的数据。在面向流的I/O中,可以将数据写入或者将数据直接读到Stream对象中。
在NIO中,所有的数据都是用缓冲区处理。这也就本文上面谈到的IO是面向流的,NIO是面向缓冲区的。
缓冲区实质是一个数组,通常它是一个字节数组(ByteBuffer),也可以使用其他类的数组。但是一个缓冲区不仅仅是一个数组,缓冲区提供了对数据的结构化访问以及维护读写位置(limit)等信息。
最常用的缓冲区是ByteBuffer,一个ByteBuffer提供了一组功能于操作byte数组。除了ByteBuffer,还有其他的一些缓冲区,事实上,每一种Java基本类型(除了Boolean)都对应一种缓冲区,具体如下:
ByteBuffer:字节缓冲区CharBuffer:字符缓冲区ShortBuffer:短整型缓冲区IntBuffer:整型缓冲区LongBuffer:长整型缓冲区FloatBuffer:浮点型缓冲区DoubleBuffer:双精度浮点型缓冲区
2.通道Channel
Channel是一个通道,可以通过它读取和写入数据,他就像自来水管一样,网络数据通过Channel读取和写入。
通道和流不同之处在于通道是双向的,流只是在一个方向移动,而且通道可以用于读,写或者同时用于读写。
因为Channel是全双工的,所以它比流更好地映射底层操作系统的API,特别是在UNIX网络编程中,底层操作系统的通道都是全双工的,同时支持读和写。
Channel有四种实现:
FileChannel:是从文件中读取数据。DatagramChannel:从UDP网络中读取或者写入数据。SocketChannel:从TCP网络中读取或者写入数据。ServerSocketChannel:允许你监听来自TCP的连接,就像服务器一样。每一个连接都会有一个SocketChannel产生。3.多路复用器Selector
Selector选择器可以监听多个Channel通道感兴趣的事情(read、write、accept(服务端接收)、connect,实现一个线程管理多个Channel,节省线程切换上下文的资源消耗。Selector只能管理非阻塞的通道,FileChannel是阻塞的,无法管理。
关键对象
Selector:选择器对象,通道注册、通道监听对象和Selector相关。SelectorKey:通道监听关键字,通过它来监听通道状态。
监听注册
监听注册在Selector
socketChannel.register(selector, SelectionKey.OP_READ);
监听的事件有
OP_ACCEPT: 接收就绪,serviceSocketChannel使用的OP_READ: 读取就绪,socketChannel使用OP_WRITE: 写入就绪,socketChannel使用OP_CONNECT: 连接就绪,socketChannel使用
NIO的应用和框架
1.NIO的应用
Java NIO成功的应用在了各种分布式、即时通信和中间件Java系统中,充分的证明了基于NIO构建的通信基础,是一种高效,且扩展性很强的通信架构。
例如:Dubbo(服务框架),就默认使用Netty作为基础通信组件,用于实现各进程节点之间的内部通信。
Jetty、Mina、Netty、Dubbo、ZooKeeper等都是基于NIO方式实现。
Mina出身于开源界的大牛Apache组织Netty出身于商业开源大亨JbossDubbo阿里分布式服务框架
2.NIO框架
特别是Netty是目前最流行的一个Java开源框架NIO框架,Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
相比JDK原生NIO,Netty提供了相对十分简单易用的API,非常适合网络编程。
Mina和Netty这两个NIO框架的创作者是同一个人Trustin Lee 。Netty从某种程度上讲是Mina的延伸和扩展,解决了一些Mina上的设计缺陷,也优化了一下Mina上面的设计理念。
另一方面Netty相比较Mina的优势:更容易学习API更简单详细的范例源码和API文档更活跃的论坛和社区更高的代码更新维护速度
Netty无疑是NIO框架的首选,它的健壮性、功能、性能、可定制性和可扩展性在同类框架都是首屈一指的,后续将重点详细谈Netty的实现原理以及实战场景。
以上,是关于BIO、NIO、AIO的知识点梳理总结。
如果觉得有用,请点赞支持下~
------end------
关注+私信发送【666】,即可领取专享福利礼包。
礼包内容:
1、【BAT架构专题100期合集】
2、【BAT面试题目及答案1000+道合集】
面试官:BIO、NIO、AIO是什么,他们有什么区别?
一、前言
书接上回,感觉上次的公司氛围不太好(其实就是女的少),还是不去了,等有了大公司要我我就再去。
今天下起了大雨,农村的空气格外的清新,呼吸起来让我非常的放松,悠然自得呀。这么好的天气不去买点熟食再买上瓶牛栏山在家喝一顿就可惜了,说干就干,披上雨披去镇上买二两牛肉。
走到了村口看到了邻居家的大美和小美,不知道她俩去哪里吃饭了,吃了一身巧克力。
我:“你俩这是去哪里吃饭了?吃的这一身巧克力。”
大美:“吃啥饭呀,厂子里下了班就回来了,回家做饭吃。”
我:“没吃饭这一身巧克力咋来的。”
小美:“刚才拐弯太猛甩出去了。”
我:“你俩也是人才。。。路这么不好走我也不去镇上买熟食了,还是回家吧,免得熟食吃不成再吃一身巧克力。”
回到家里躺沙发上打开电视,这下雨天看看电视也挺美滋滋呀。突然电话响了。
我:“喂您好”。
对面:“您好,请问是小奇吗”。
我:“是我,你是?”。
对面:“我是XXX公司的,我看到hr推给我你的简历,我感觉还不错,你什么时候方便来现场面试一下”。
我:“现在不方便现场面试了”。
对面:“好吧,那你现在方便吗?我们现在线上面试一下吧”。
我:“好的”。
二、面试
面试官:“你能说一下网络IO模型吗?”
我:“网络IO模型有BIO、NIO、AIO ”。
面试官:“他们分别代表什么,有什么区别吗?”
BIO:同步阻塞IO。
NIO:同步非阻塞IO。
AIO:异步非阻塞IO。
面试官:“BIO为什么是同步阻塞IO,他阻塞的是谁跟谁之间的关联?”。
首先在网络编程中,客户端给服务端发送消息大约分为两个个步骤。
1、发起连接。
2、发送数据。
在BIO中每一个连接都需要分配一个线程来执行,假如A客户端连接了服务器,但是还没有发送消息,这个时候B客户端向服务器发送连接请求,这个时候服务器是没有办法处理B客户端的连接请求的。
因为一个线程处理了一个客户端的连接后就阻塞住,并等待处理该客户端发送过来的数据。处理完该客户端的数据后才能处理其他客户端的连接请求。
面试官:“那你这个是只有一个线程的时候,那我弄多个线程不就好了,来一个请求连接我弄一个线程”。
我:“那假如有一万个连接请求同时过来,那你开启一万个线程服务端不就崩了嘛。”
面试官:“那我弄一个线程池呢,我最大线程数最多弄500呢?”。
我:“那假如有500线程只请求连接,并不发送数据呢,那你这个线程池不也一样废了吗。这500个请求连接上了还没有发送数据,那么线程池的500个线程就没办法去处理别的请求,这样照样废废了。”
面试官:“那咋办呢?”。
我:“别慌,哥有办法,可以使用NIO同步非阻塞,这样就不需要很多线程,一个线程也能处理很多的请求连接和请求数据。”
面试官:“NIO他是怎么实现一个线程处理多个连接请求和多个请求数据的呢?”。
我:“NIO会将获取的请求连接放入到一个数组中,然后再遍历这个数据查看这些连接有没有数据发送过来
面试官:“这招高啊”。
我:“那必须滴。”
面试官:“但是有个问题啊,如果B和C只连接了,但是一直没有发送数据,那每次还循环判断他俩有没有发送数据的请求是不是有点多余了,能不能在我知道B和C肯定发送了数据的情况下再去遍历他呢?”。
我:“那你让客户B和客户C发送数据的时候给你打一个电话不就行了,然后你就只遍历他俩。”
面试官:“他们也不能够给我打呀,你再想一个别的办法”。
我:“可以引入Epoll,在JDK1.5开始引入了epoll通过事件响应来优化NIO,原理是客户端的每一次连接和每一次发送数据都看作是一个事件,每次发生事件会注册到服务端的一个集合中去,然后客户端只需要遍历这个集合就可以了。”
面试官:“那AIO有什么特点呢?”
我:“AIO是异步非阻塞,他对于客户端的连接请求和发送数据请求是用不同的线程来处理的,他是通过回调来通知服务端程序去启动线程处理,适用于长连接的场景。”
面试官:“小伙子不错呀,什么时候能回北京入职呢”
我:“额。。。等等吧,现在家里雨太大了,容易弄一身巧克力。”
面试官:“行,那你来了北京一定来我们公司上班啊”
我:“额。。。这个跟你承诺不了,万一还有别的好公司给我打电话呢”。
面试官:“来吧,条件好商量”
我:“我考虑考虑吧”。
三、总结
这里关于网络编程模型还没有整理完毕,文章后面持续更新,建议收藏。
文章中涉及到的命令大家一定要像我一样每个都敲几遍,只有在敲的过程中才能发现自己对命令是否真正的掌握了。
相关问答
Biodiversity 这个词的构成,bio是个前缀吗_沪江网校知识库没错哦bi(o)是一个词根,表示生命、生物的意思。类似的单词还有很多~例如:biology生物学biochemistry生物化学antibiotic抗生素希望可以帮到...
bio 是哪个国家的?Bio是一个通用的词语,可指生命,生物科技或生物学等。因此,它没有特定的国籍或起源地。然而,如果指的是生物科技公司BioNTechSE,那么它的总部位于德国马恩海...
bio 是什么牌子?美国BIO是一种利用人体微电技术研制的美容仪,其所发出的微电流经过皮肤进入肌肉细胞,在毫无感觉下刺激细胞内所蕴藏的能量(ATP三磷酸腺酣),大量、直接、有效...
bio 食品是什么意思?bio食品就是有机食品。BIO在欧洲许多国家是“纯天然”的.标志。标示有BIO的食品一般是有机食品,价格比普通食品贵很多而标有BIO的化妆品则是指用纯天然的原...
bio 医学上是什么意思?词根bio=life生命,生物。bio也作bi。由此可知,bio在医学上是生命,生物的意思。举例如下:1、biology〔bio生物,-logy...学〕生物学。2、biogra...
bio 有机是指什么?BIO就是蔬菜和粮食的种子非转基因(OGM)并且要在自然的环境中成长,时令性,不使用化学农药,化肥等。加工时不使用化学添加剂。满足了这些条件,严格意义上基本就...
bio 是什么化学名称?BIO是吩臭酪氨酸的缩写。酪氨酸(tyrosine;Tyr)的化学名称为2-氨基-3-对羟苯基丙酸,它是一种含有酚羟基的芳香族极性α-氨基酸。酪氨酸是人体的条件必需氨基...
bio 是什么前缀?bⅰo是生命,双向前缀。例bⅰology生物学bⅰo是生命,双向前缀。例bⅰology生物学
bio 开头单词特点?生物学方面的,比如biology,biography生物学方面的,比如biology,biography
bio 溶脂片怎么吃比较好[回答]bio-e晚安溶脂片的吃法还是特别简单的,一天当中最好选择晚上睡觉前服用,建议每天晚上服用一次,一次服用三片就可以了,温开水送服能够帮助更好的溶解...