面试常考JavaNIO和Linux多路复用机制
7月15日 红朱砂投稿 1、同步阻塞式IONIO
BIO就是BlockingIO的简称,Java中BIO是由ServerSocket负责绑定IO地址启动监听端口等待客户端连接。客户端的Socket类发起连接。BIO的阻塞主要体现在:服务端程序启动后,会一直等待客户端的连接,在此期间线程是阻塞的,不能干其他的事。在连接建立后,在读取到socket数据之前,线程仍然是阻塞状态。2、同步非阻塞式IONIO
NIO是JDK1。4版本引入的,NIO弥补了BIO的种种不足,BIO是面向字节流,而NIO则是面向缓冲区。BIO在调用read、write等方法时,线程会阻塞,直到有数据到达。NIO的非阻塞模式下,线程从某个通道读取数据,如果没有可用的数据时候就不会阻塞,可以去做其它事情。一个独立的线程管理多个输入和输出通道,这样可以将阻塞等待时间拿来在其它通道上执行IO操作。NIO有三大核心组件:
2。1Selector选择器
Selector选择器又称为事件订阅器、轮询代理器,Java的NIO的Selector选择器允许一个单独的线程来监视多个通道,然后使用一个单独的线程拿来操作这个选择器。客户端向Selector注册它所关注的某个通道Channel以及关注的哪些事件(例如连接事件、读取事件等),当然Selector中会维护一个Channel列表。
2。1。1SelectionKey
这个key代表channe通道在Selector上注册的唯一标识。
2。1。2Selector注册事件类型OPREAD读事件:当读缓冲区有数据可读时触发的事件。OPWRITE写事件:当写缓冲区有空间空间时触发的事件。OPCONNECT连接事件:connect()请求连接成功后触发的事件,给客户端使用。OPACCEPT连接请求事件:accetp()当接收到一个客户端连接请求时触发的事件,给服务端使用。
2。2Channels通道
channel通道,是对应用程序和操作系统交互数据通道的抽象。应用程序可以通过通道读取数据也可以通过通道向操作系统写入数据。
2。3Buffer缓冲区
JDK的NIO是面向缓冲区的,这个Buffer就是缓冲区,用于和通道进行交互。数据从Channel读入缓冲区,也可以从缓冲区写入通道。Buffer的本质其实就是字节数组,JDK提供了一系列的方法来操作访问这个Buffer对象。
2。3。1Capacity
代表Buffer缓冲区的容量。
2。3。2Position
代表当前写入数据的相对偏移量。
2。3。3Limit
写模式下,limit代表最多能往Buffer里面写多少数据,此时limitcapacity。读模式下,limit代表最多能读多少数据。
2。3。4Buffer缓冲区的分配HeapByteBuffer:在JVM的堆空间中分配,在发送阶段会先从堆空间拷贝到直接内存,然后再通过操作系统的内核态切换和拷贝到网卡缓冲区。DirectByteBuffer:直接分配在直接内存,性能上相对于堆内存更快,但是在大容量或者频繁的申请直接内存可能导致性能下降。3、Reactor模型
Reactor模型是对事件处理流程的一种模式抽象,是对IO多路复用模式的一种封装,Reactor又叫反应器,在这里特指的是对各种事件的反应处理。Reactor模型有2个重要的组件:Reactor:专门用于监听和响应各种IO事件,例如连接事件、读事件、写事件等,当检测到有一个新的事件发生时,就会交给相应的Handler去处理。Handler:专门用来处理特定的事件的执行者。
3。1单Reactor单线程模型
服务端的Reactor线程对象,不断循环监听各种IO事件,还会注册一个accepter的特殊Handler到Reactor中,这个accepter专门负责处理连接的事件。客户端发起请求,服务端的Reactor监听到accept事件,然后将这个accept事件分派给accepter组件,accepter组件通过accept()方法和客户端建立对应的channel。然后将这个连接所关注的read事件注册到Reactor中,这样Reactor就会监听read事件的发生。当服务端Reactor监听到read事件,将这个read事件发送给对应的读请求Handler进行数据的读取。
3。1。1单Reactor单线程模型的优点
最基础的Reactor模型,实现简单,不用考虑并发问题。JDK的NIO的Selector选择器就是最简单的单Reactor单线程模型。
3。1。2单Reactor单线程模型的缺点
Reactor和Handler的所有操作都是在同一个线程中完成的,无法充分利用多核优势,性能不佳。Redis6。0之前就是典型的单Reactor单线程模型,虽然6。0以后引入了多线程,但是它的多线程只是用来处理耗时的网络IO操作上,实际执行命令的Handler仍然是单线程。
3。2单Reactor多线程模型
大体上单Reactor多线程模型和基本的单Reactor单线程模式差不多,只不过单Reactor多线程模型多引入了一个线程池,这个线程池负责将一些非IO操作的事件进行处理,例如计算、编解码任务等。虽然这种模式下引入了线程池,效率得到了一定的提升,但是毕竟是采用单Reactor架构,所有的事件都是交给单个Reactor负责,在面对瞬间的高并发连接场景,单Reactor多线程模型仍然性能不佳。
3。3多Reactor多线程模型(主从Reactor模型)
为了优化单Reactor模型的性能瓶颈,将原来单独的Reactor的功能进行分解为连接处理器和通信处理器,由多个不同的Reactor共同完成网络通信任务。主Reactor拥有自己的Selector,通过select监控连接事件,事件发生后交给accepter组件处理,然后accepter组件将连接分配给某一个从Reactor。从Reactor也有自己的Selector,从Reactor监听并执行读、写等事件。线程池的任务没有变化,负责处理非IO的事件任务,例如编解码序列化、计算等。主从Reactor模型中,主Reactor和从Reactor都可以存在多个,每个Reactor都有自己的Selector,都是独立的线程工作,这样充分利用了多核CPU的优势。
但是多Reactor多线程架构仍然不能根治IO操作对其他Client的效能影响,毕竟有可能某个从Reactor可能有多个client的连接。所以诞生了异步IO模型的Proactor模型来实现真正的异步IO。Netty、Memcached、Nginx都是采用的多Reactor多线程的模型。不过Netty支持多种Reactor模型的配置。4、Linux网络IO模型
4。1同步和异步、阻塞和非阻塞的区别同步:调用方需要主动等待结果的返回。异步:调用方调用了函数不需要等待结果的返回,后续通过回调等手段来处理结果。阻塞:在调用方拿到结果之前,线程会被挂起,不能做任何事。非阻塞:在调用方拿到结果之前,线程可以执行一些其他的事情,不会被挂起。
4。2同步、异步、阻塞、非阻塞的相互组合模式同步阻塞模式:最常见的组合模式,调用方在拿到结果之前,线程处于挂起状态,直到有数据触达为止。同步非阻塞模式:调用方发起了函数调用,通过轮询的方式来检查结果,这个过程线程并未阻塞,但是轮询的目的是等待结果的返回。异步阻塞模式:最不常用的方式,这种方式没有发挥出异步的真实效果。异步非阻塞模式:调用方发起函数调用后,给接受方一个回调函数,然后自己去执行其他的方法。后续接受方有了数据后主动调用回调函数来实现结果的返回。
4。3Linux的5种IO模型
Linux的5种IO模型:阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO,前面四种都是同步的模式,只有最后一种是异步的。注:Java的BIO和Linux的BIO是一致的,但是Java里面的NIO对应的是Linux的IO多路复用。
下面几张图片取材自百度,因为比较通用我就没有自己画了。
4。3。1阻塞式IO(BIO)
4。3。2非阻塞式IO(NIO(并非Java里面的NIO))
4。3。3IO多路复用
IO多路复用的方式会有2次系统调用,从这一点看并不比BIO有优势。IO多路复用相比于BIO来说最大的优势就是可以用select少量的线程处理多个连接请求。所以,在连接量少的情况下,BIO的效率反而更好,IO多路复用则是在大连接量场景有优势。
4。3。4信号驱动式IO
通过进程的SIGIO信号作为事件驱动来进行IO的处理,这种模式运用比较少。
4。3。5异步IO模型
5、Linux的IO多路复用
IO多路复用机制就是通过一个进程可以监视多个文件描述符,一旦有socket描述符就绪,就能够通知应用程序做对应的读写处理。
5。1文件描述符FileDescriptor(FD)
在Linux系统中,文件、外接设备、套接字socket都视为文件,统一文件接口方便操作系统访问。同理,Socket套接字也是一种文件,当应用程序请求内核打开一个文件时,内核就会为此返回一个文件描述符。
5。2IO多路复用的实现方案
Linux的IO多路复用有3种实现手段:select、poll、epoll:
5。2。1select
select函数可以监视3类文件描述符:writeFds、readFds、execptFds。调用select函数后进程会阻塞,直到有就绪的文件描述符。当select又返回时,就会唤醒进程来处理io事件,而且是会遍历整个描述符数组来处理就绪的io事件。select的优点是跨平台支持,缺点是单个进程的文件描述符是有OS控制的,Linux最大是1024个,但是可以修改。另一个缺点就是需要遍历整个文件描述符数组。
5。2。2poll
和select十分相似,只不过poll对文件描述符的管理时基于链表,而且poll没有限制描述符数量,当连接量较大时性能会急剧下降。和select一样,调用poll函数后,一旦有就绪事件需要轮询整个链表。
5。2。3epoll
epoll是在Linux2。6版本推出的一种IO多路实现手段。相对于poll和select,epoll做了很大优化和改进。
epoll的优化思路有2点:功能分离:创建epoll、socket监视注册、等待数据分为3个API实现。就绪列表:select和poll低效的根本原因是要遍历所有的socket,epoll则维护了一个就绪列表,引用了收到了数据的socket,这样就避免了全链表扫描。
当socket收到数据后,中断程序会操作eventpoll,将对应的socket挂载到就绪列表里面,后续恢复进程来处理,此时只需要处理就绪列表里面的socket。当进程调用epollcreat函数时,Linux内核会创建一个Eventpoll结构体,然后在内核缓冲区中创建一个红黑树来存储后续连接注册的socket,然后也会在Eventpoll中创建一个就绪链表。后续只需要监听这个链表有没有就绪的socket即可。epoll相对于select和poll有了很大的优势,保持数万数十万连接也不是问题。但是在极端情况下,例如就序列表的元素十分多时,也会有瓶颈。
5。3触发方式
5。3。1水平触发LT
当被监控的文件描述符上有可读写事件发生时,epollwait()会通知应用程序去读写,如果这次读写没有处理完数据,那么下次调用epollwait()是,OS还会继续通知应用程序继续读写,如果你一直不处理完数据,OS会一直通知你。
5。3。2边缘触发ET
和水平触发不同的是,应用程序没有处理完这一次通知事件的数据时,调用epollwait()时OS并不会通知你有数据读写事件,直到这个文件描述符上出现第二次可读写事件发生时才通知应用程序。这种方式相比LT,ET更加清净,一般来说ET性能要高于LT,但是实际应用中看不出有啥大区别。
作者:Minor
链接:https:juejin。cnpost7120529881229852685
投诉 评论
平鲁人看平鲁李生财美不美,家乡水;亲不亲,故乡人。这是人们流淌在血液里,镌刻在骨髓里对家乡的一种深深的热爱。我对家乡有一种特殊的情愫,家乡在我心中的分量是世界上任何繁华闹市都无可替代的。这里留下……
患了高压后,请自觉管住嘴这3种食物劝你不要碰王叔,48岁,有非常大的酒瘾,几乎每顿饭都要喝酒,饮酒史二十多年,最近一次体检发现血压过高,体检医生建议王叔系统检查一下,于是王叔去内科挂了个号。通过王叔的主诉,我们了解……
日常生活中如何保护牙齿?1、正确刷牙每日至少刷两次牙,每次刷牙时间不少于3分钟,并使用竖刷法或巴氏刷牙法,避免使用粗暴的横刷法刷牙。2、使用牙线牙签剔牙容易刺伤牙龈,因此建议大家使用……
一起玩派对游戏吧走访纽约街机酒吧Wonderville封面:《NaissanceE》位于纽约布鲁克林的Wonderville是由MarkKleback和StephanieGross夫妻二人创立的独立街机游戏体验馆兼酒吧。馆内……
小米13Ultra配置曝光,后置四摄IMX989超大底加持13月27日消息,在vivo、OPPO、荣耀相继发布了自家的影像旗舰后,还有一位影像旗舰缺席,那便是小米13Ultra了,将在4月11号发布。图片来源网络目前可以了解……
为什么说伦纳德是MVP级别的球员?他统治了攻防两端,并且高效快船以108:100战胜猛龙后,网友喊话伦纳德,看篮板就知道你是认真的。为什么网友会这样说呢?本场比赛伦纳德带领快船战胜猛龙并得到24分12篮板4助攻3抢断,几乎填满了数……
张碧晨不得不说的故事张碧晨和华晨宇有什么故事?张碧晨是一位音色很好、创作能力很强的女歌手。她凭借自己超人一等的歌唱技巧和表演,她曾获得中国好声音年度总冠军。她的声音很独特且有吸引力,所……
发烧音响进阶入门必听的第二课活生感(文字版)耳听乐动本无意,谁知韵生暗香来,恰是春风扰幽梦,半话余生半思缘。听音乐本就是十分奇妙的事情,品得三分滋味,余韵悠长,了却此生残思。念头通达。好了开场到此,言归正传。……
荣耀手机推荐,最适合女生使用,还有高性价比最近荣耀又要出新机了,似乎自从华为mate50和iPhone14发布之后,各家新机上市的频率都开始逐渐降低了,但是荣耀却出现了。先发布了荣耀X40,如今荣耀X40GT的消息也已……
多款APP停运收入下降56,腾讯怎么了?腾讯半年报一出,其收入下降56,堪称史诗级缩水。外加腾讯今年大搞裁员、停运多款APP、削减员工福利,万亿腾讯帝国到底出了什么问题?其实随着人口进入负增长,腾讯依靠人……
61亿元!衢江区2大文旅项目列入浙江省千项万亿工程近日,全省文化和旅游深度融合发展动员部署会在杭州召开,会上发布全省《2023年文化和旅游投资双百计划重大项目清单》。衢江区尺方间文化创意园、衢江姑蔑古国考古遗址博览园共2……
国乒男队历任队长,全部拿过世界冠军,你认识几个?你知道国乒男队历任队长都是谁吗?他们一个比一个厉害,在职业生涯中拿冠军拿到手软,他们没有一个是简单的人物。今天就来盘点国乒20余年,历任男队队长人物。第一任刘国梁。刘国梁……