BIO&NIO&AIO模型快速实战

BIO 同步阻塞IO

大白话介绍

  • 一次只能处理一个连接,BIO它的连接和读数据都是阻塞的。

理论介绍

  • 同步阻塞,服务器实现模式一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。

弊端:

  1. 阻塞 (最大问题,如果处理500个请求,但是有499个没有给我返回数据,那么我就一直在这阻塞住了)
  2. 并发效率低(一次只能处理一个请求)
  3. 线程太多了(因为你每发来一个请求都会去开一个线程,那么如果这个时候过来100万个请求那么就需要开100万个线程,服务器怎么可能抗的住)
    image

代码介绍

  1. 首先建立客户端连接
  2. socket.accept()监听客户端连接
  3. 如果没有人来连接,那么就会一直卡在这里,直到有人来连接才会往下走
  4. 获取他的输入输出流,获取到后存放一个空间里面,存到数组里面
  5. 使用读的流把数据读出来,如果有一个客户端连接上我这个服务器
  6. 但是并不给我这个服务器发消息
  7. 然后我们这个服务就会一直卡在这里,然后客户端连接的哪个代码就永远得不到执行了
  8. 直到这个客户端给我们服务端发来消息,然后服务端才能去接收下一条消息

BIO开的线程太多了 NIO就是解决这个问题!!!

BIO是怎么延伸到NIO的?

  1. NIO它把两个阻塞的方法accept()和rend()给改掉了,改成非阻塞的方法
  2. 防止没有人来连接,也一直在跑浪费性能的问题上呢我们增加一个list集合
  3. 然后如果有请求进入了 才去添加到list集合中去,然后到时候直接遍历list集合就能去看我们请求了

NIO 同步非阻塞

大白话介绍

  • 设置configureBlocking()方法为非阻塞状态
  • 就算到时候接受不到发来的数据,那么NIO也不会阻塞

理论介绍

  • NIO 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到 多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。用户进程也 需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问

弊端:

NIO单线程的缺点:
性能太慢了,一个线程处理不过来。如果发送10000个请求,每个请求逗得经历编码解码之类的操作,那性能太慢了。

代码分析

  1. 首先打开一个选择器对象selector
  2. selector专门用来存放socket的
  3. 然后打开一个服务端
  4. 设置configureBlocking()方法为非阻塞状态
  5. 然后把socket添加到集合当中和绑定连接事件
  6. 如果一旦有客户端连接我了,那就能触发连接事件
  7. 然后到时候通过调用select()方法查看是否有事件发生,如果有则把这个事件加入集合当中,继续执行
  8. 遍历集合看看有没有事件发生

*BIO不知道什么时候有人来连接它,也不知道什么时候能发来消息,但是NIO改变了这个思路,它是倒着过来的NIO只给某个对象指定事件,一旦有事件发生了就告诉我,由操作系统告诉我。

AIO

理论介绍

  • AIO 异步非阻塞,在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO 操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对 数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入 操作已经由内核完成了

BIO、 NIO、AIO适用场景分析

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高, 并发局限于应 用中,JDK 1.4以前的唯一选择,但程序直观简单易理解。
  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK 1.4开始支持。
  • AlO方式使用于连接数目多且连接比较长(重操作) 的架构,比如相册服务器,充分调用OS参与并 发操作,编程比较复杂,JDK 7开始支持。
posted @   来自未来的信  阅读(70)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示