几种 IO编程比较

几种 IO编程比较参考:Netty权威指南第一版Java网络IO编程总结(BIO、NIO、AIO均含完整实例代码)1.传统的BIO模型通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行处理,处理完之后,通过流返回应答给客户端,线程销毁。这就是典型的—请求—应答通信模型。该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发量增加后,服务端的线程

大家好,又见面了,我是你们的朋友全栈君。

参考:
Netty权威指南第一版
Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

1. 传统的BIO模型

通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行处理,处理完之后,通过流返回应答给客户端,线程销毁。这就是典型的—请求—应答通信模型。

该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发量增加后,服务端的线程个数和客户端并发访问呈1:1的正比关系,由于线程是java虚拟机非常宝贵的系统资源,当线程数膨胀以后,系统的性能将急剧下降,随着并发访问量的继续增大,系统会发生线程堆溢出、创建新线程失败等问题,并最终导致进程宕机或者僵死,不能对外提供服务。

2. 伪异步IO编程

对同步阻塞IO面临的问题,后来有人对它的线程模型进行了优化,后端通过一个线程池来处理多个客户端的请求接入,形成客户端个数M :线程池最大线程数N的比例关系,其中M可以远远大于N,通过线程池可以灵活的调配线程资源,设置线程的最大值,防止由于海量并发接入导致线程耗尽。

该方式避免了为每个请求都创建一个独立线程造成的线程资源耗尽。但是由于它底层的通信依然采用同步阻塞模型,因此无法从根本上解决问题。

分析:
如果每个read操作都阻塞,导致线程池很快饱和,将不能继续处理新的请求,导致服务不可用。

3. NIO编程

相关概念:

  1. 缓冲区Buffer

    • ByteBuffer:字节缓冲区
    • CharBuffer:字符缓冲区
    • ShortBuffer:短整型缓冲区
    • IntBuffer:整型缓冲区
    • LongBuffer:长整型缓冲区
    • FloatBuffer:浮点型缓冲区
    • DoubleBuffer:双精度浮点型缓冲区
  2. 通道

  3. 多路复用Selector

4. AIO编程

JDK1.7 提供了NIO2.0, 引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。异步通道提供两种方式获取操作结果:

  • 通多java.util.concurrent.Future类来表示异步操作的结果
  • 在执行异步操作的时候传入一个java.nio.channels

NIO2.0 的异步套接字通道是真正的异步非阻塞IO,它对应UNIX网络编程中的事件驱动IO(AIO),它不需要通过多路复用器(Selector)对注册的通道进行轮训操作即可实现异步读写,从而简化NIO的编程模型。

AIO是真正的异步非阻塞的,所以,在面对超级大量的客户端,更能得心应手。

5. 4种IO比较

概念澄清

  • 异步非阻塞IO

    很多人习惯将JDK1.4提供的NIO称为异步非阻塞IO,其实严格按照UNIX网络编程模型和JDK实现区分,实际上它只能被称为非阻塞IO,不能叫做异步非阻塞IO。在早期JDK1.4和1.5 update10版本之前,JDK的Selector基于select/poll模型实现,它是基于IO复用技术的非阻塞IO,不是异步IO。在JDK1.5 update10和Linux core2.6以上,Sun优化了Selector的实现,它在底层使用epoll替换了select/poll,上层的API没有变化,可以认为是JDK NIO的一次性能优化,但是它仍旧没有改变IO的模型。

    JDK1.7提供的NIO2.0才真正的异步IO。

  • 多路复用器Selector

    将Selector翻译成选择器体现不出Selector的功能和特点,翻译为多路复用器更为合适。

  • 伪异步

    伪异步IO完全来自实践,后端采用线程池来处理IO任务。

对比

IO模型对比

结语

具体代码可查阅《Netty权威指南》或者参考博客Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132487.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机测试英语词汇,英语听说测试-计算机专业英语词汇.pdf「建议收藏」

    英语听说测试-计算机专业英语词汇常用计算机专业英语1.filen.文件;v.保存文件43.enterv.键入,送入2.commandn.命令,指令44.marginn.余量,边缘,边际3.usev.使用,用途…

    2022年4月17日
    31
  • zookeeper入门教程_dubbo和Zookeeper详解

    zookeeper入门教程_dubbo和Zookeeper详解zookeeperwatcher架构zookeeper 配置中心分布式ID分布式锁集群搭建数据一致性协议:zab协议Zookeeper Leader选举Observer角色及其配置watcher架构客户端首先将Watcher注册到服务器,同时将Watch对象保存到客户端的Watch管理器中。当Zookeeper服务器监听到的数据发生变化时,服务器会通知客户端,接着客户端的Watch管理器会触发相关的Watcher来回调响应处理逻辑,从而完成整体的数据发布/订阅流程。javaAPIJava

    2022年8月8日
    1
  • SpringBoot整合Druid「建议收藏」

    SpringBoot整合Druid「建议收藏」SpringBoot整合DruidDruid简介配置数据源配置Druid数据源监控Druid数据源具有监控的功能,并提供了一个web界面方便用户查看,类似安装路由器时,人家也提供了一个默认的web页面。Druid简介Java程序很大一部分要操作数据库,为了提高性能操作数据库的时候,又不得不使用数据库连接池。Druid是阿里巴巴开源平台上一个数据库连接池实现,结合了C3P0、DBCP等DB池的优点,同时加入了日志监控。Druid可以很好的监控DB池连接和SQL的执行情

    2022年7月23日
    17
  • 联合体(union)的使用方法及其本质

    联合体(union)的使用方法及其本质有些基础知识快淡忘了,所以有必要复习一遍,在不借助课本死知识的前提下做些推理判断,温故知新。1.联合体union的基本特性——和struct的同与不同union,中文名“联合体、共用体”,在某种程度上类似结构体struct的一种数据结构,共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。不过区别也挺明显:结构体(struct)中所有变量是“共存”的…

    2022年6月2日
    33
  • 如何在Python中将列表转换为字符串?

    如何在Python中将列表转换为字符串?Pythonprovidesdifferentvariabletypeforprogrammersusage.Wecanuseint,float,string,list,set…datatypesinourapplications.Whileusingdifferenttypeofvariableswemayneedtoconvert…

    2022年4月30日
    92
  • github开源可视化_可视化拖拽项目管理 github

    github开源可视化_可视化拖拽项目管理 githubGIT下载:国内太慢甚至下载不了的解决方法。在淘宝的镜像网站上下载: https://npm.taobao.org/mirrors/git-for-windows/gitconfig

    2022年8月2日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号