Java|BIO、NIO、AIO Dear 丶 2024-04-17 06:01 75阅读 0赞 在很多面经里都有这样的问题: * 说说BIO、NIO、AIO * 说说Linux的IO模型 * 说说select、poll、epoll 最开始对这些名词一点都摸不着头脑,粗略了解了BIO、NIO、AIO是什么,其中涉及到“同步/异步、阻塞/非阻塞"这些名词,更是被搞的云里雾里。BIO是在学习JavaSE的时候,网络编程讲的内容,大概知道是怎么回事,但从来没有思考过它有什么问题。对于select、poll、epoll这几个Linux底层的函数,找了些Linux的书去看,因为过于细节,看得人好生艰难,至少对于一个这方面还没入门的人不友好。我们需要先有一个大致的场景,对这些问题形成一点系统性的认识,将它们形成一个体系。在看redis的时候看到了“IO多路复用”几个字,刚好和自己看不懂的IO相关,就去看了看Redis的事件模型,好像从这个时候,开始大致理解这几个问题。努力去找相关的资料去看,把所有的云里雾里综合到一起,却逐渐显现了一条线索,对这几个问题有一个大概的认识。 首先我们要认识到,关注这个问题,是因为它可能造成性能瓶颈。 从小白的角度理解,CPU处理非常的快,但执行IO操作的时候,我们却需要让宝贵的线程资源阻塞,等待IO。例如`Scanner sc = new Scanner(System.in);`写算法题的时候,通常这样处理输入,运行这一句,程序就会阻塞在那里,等待我们输入了数据,才能继续执行下去。 我们都写过传统BIO的小例子,例如模拟一个服务器和客户端交换信息,服务器在一个`while(true)`里通过`Socket s = ss.accept();`等待客户端的连接,当客户端连接后创建新的线程执行客户端任务,accept()过程是阻塞的,而在后面的读写数据的过程也是阻塞的。如果只有一个客户端(像我们模拟的那样),那当然没问题,阻塞着就阻塞吧,就是为你一个人服务的。但如果有非常非常非常非常多的客户端去连接服务器呢?——我们就要创建非常多的线程去处理客户端的任务。但是线程的创建和销毁成本很高并且线程本身需要内存的。所以无限制的创建线程OS是承受不起的。 啊,我不想在这里分析BIO的问题,下面列出的资料已经非常清晰明了的解释了这系列的问题。这篇只是记录一下自己对这个知识点的认识过程,稍微梳理一下知识点的层次关系。 从“说说BIO、NIO、AIO”开始: 1. 先说概念BIO(Blocking IO)、NIO(Non-blocking IO)、AIO(Aysnchronous IO) 2. 说说关注IO是因为可能造成性能瓶颈(这里可以引出BIO了) 3. 依次讲BIO是什么,存在的问题是什么,NIO是什么,和BIO有什么不同,它解决了什么问题,AIO是什么,AIO的特点是什么,和BIO、NIO大概有什么不同 4. 这里可以讲一下Linux系统的五种线程模型了 5. 接着分析NIO,先从语言层面(Selector Buffer Channel),再讲底层实现(epoll) 6. 讲一下为什么有了NIO还要AIO,现在一般使用什么 7. JDK对NIO的封装不太友好,一般用Netty,可以大概介绍一下Netty原理(一丢丢) 哈哈,好了,上链接: 1. Linux的五种IO模型:[漫话:如何给女朋友解释什么是Linux的五种IO模型?][Linux_IO] 2. Java NIO非常好的文章:[Java NIO浅析][Java NIO] 3. 对Netty的大概了解:[彻底理解Netty,这一篇文章就够了][Netty] 4. 顺便可以了解一下Redis的线程模型,为什么单线程但能够高性能、高并发 [Linux_IO]: https://mp.weixin.qq.com/s?__biz=Mzg3MjA4MTExMw==&mid=2247484746&idx=1&sn=c0a7f9129d780786cabfcac0a8aa6bb7&source=41#wechat_redirect [Java NIO]: https://zhuanlan.zhihu.com/p/23488863 [Netty]: https://segmentfault.com/a/1190000017128263?utm_source=tag-newest
还没有评论,来说两句吧...