java支持3种网络编程模型,以及在web项目中的应用

之前有总结过linux中的5种IO模型

https://blog.csdn.net/weixin_45068892/article/details/127424119

本次主要讲一下java中支持的IO模型。

Java共支持3种网络编程IO模式,及应用场景

BIO

NIO

AIO

https://blog.csdn.net/CSDN_GIA/article/details/128535848

BIO

基本介绍

适用场景: 连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JKD1.4以前的唯一选择,但程序简单易理解。

缺点:一个客户端连接对应一个处理线程,没办法同时处理多个连接

改进:多线程处理

来一个客户端,开启一个新的线程在后端处理

弊端:C10K问题

connect 10*1000个连接:

服务端扛不住,内存不够

链接太多,服务端资源不够

改进:使用线程池:

但是这样 并发数也就限制在了线程池的数量这里

NIO

基本介绍

  • Java NIO(New IO)也称之为 java non-blocking IO是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。NIO可以理解为非阻塞IO,传统的IO的read和write只能阻塞执行,线程在读写IO期间不能干其他事情,比如调用socket.read()时,如果服务器一直没有数据传输过来,线程就一直阻塞,而NIO中可以配置socket为非阻塞模式。

  • NIO 相关类都被放在 java.nio 包及子包下,并且对原 java.io 包中的很多类进行改写。

  • NIO 有三大核心部分:Channel( 通道) ,Buffer( 缓冲区), Selector( 选择器)

  • Java NIO 的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。

  • NIO可以做到用一个线程来处理多个操作。假设有 1000 个请求过来,根据实际情况,可以分配20 或者 80个线程来处理。不像之前的阻塞 IO 那样,非得分配 1000 个。

适用场景:

连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。编程复杂,JDK1.4开始支持

NIO 和 BIO 的比较

  • BIO 以流的方式处理数据,而 NIO 以块的方式处理数据,块 I/O 的效率比流 I/O 高很多
  • BIO 是阻塞的,NIO 则是非阻塞的
  • BIO 基于字节流和字符流进行操作,而 NIO 基于 Channel(通道)和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道

IO多路复用 = NIO + Selector

原始的NIO:

多路复用的NIO:

基于epoll的NIO:

I/O多路复用底层主要用的Linux 内核·函数(select,poll,epoll)来实现,windows不支持epoll实现,windows底层是基于winsock2的select函数实现的(不开源)

Redis线程模型

Redis是典型的基于epoll的NIO线程模型(nginx也是),epoll实例收集所有事件(连接与读写事件),由一个服务端线程连续处理所有事件命令。

Redis底层关于epoll的源码实现在redis的src源码目录的ae_epoll.c文件里。

AIO

基本介绍

Java AIO(NIO.2) : 异步非阻塞,基于NIO的,可以称之为NIO2.0,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理,一般适用于连接数较多且连接时间较长的应用。

适用场景:

连接数目较多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

三种IO比较

特点:

Java BIO : 同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

Java NIO : 同步非阻塞,服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

Java AIO(NIO.2) : 异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理。

适用场景:

BIO:适用于连接数目少,而且服务器资源对于我们已知的连接来说,比较充足,开发简单;对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

NIO:相对BIO来说,开发难度较高,但是客户连接数目比较高。值得我们注意的是,由于NIO是单一的线程轮询来处理数据,需要避免每个任务执行的时间过长,防止其他线程出现过长的等待;适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO:接受的连接数目多,相对于NIO来说,是异步出来,可以接受某个任务花费过长的时间,但是开发难度比较高,维护起来也不简单。适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

相关推荐
无敌最俊朗@2 分钟前
Qt事件循环队列剖析!!!
java
v***56515 分钟前
Spring Cloud Gateway 整合Spring Security
java·后端·spring
python零基础入门小白33 分钟前
【万字长文】大模型应用开发:意图路由与查询重写设计模式(从入门到精通)
java·开发语言·设计模式·语言模型·架构·大模型应用开发·大模型学习
天若有情67341 分钟前
【c++】手撸C++ Promise:从零实现通用异步回调组件,支持链式调用+异常安全
开发语言·前端·javascript·c++·promise
会飞的土拨鼠呀1 小时前
通过Linux进程id找到程序路径
linux·服务器·网络
高山上有一只小老虎1 小时前
构造A+B
java·算法
GIS数据转换器1 小时前
GIS+大模型助力安全风险精细化管理
大数据·网络·人工智能·安全·无人机
学困昇1 小时前
C++中的异常
android·java·c++
抱琴_1 小时前
【Vue3】大屏性能优化黑科技:Vue 3 中实现请求合并,让你的大屏飞起来!
前端·vue.js