IO底层原理与Java NIO

IO流程示意图

在这里插入图片描述

客户端发送数据来到服务器,建立好sokcet连接再到应用程序拿到这个数据可以分为两个步骤

因为应用程序是没办法直接去网卡读取数据的,应用程序向OS内核发起read调用

1.数据准备(输入流从网卡来到OS内核空间)

2.数据拷贝(从内核空间拷贝到用户空间)

根据应用程序接收结果的通知方式分为 同步和异步。简单理解:同步就是应用程序发起read调用之后就一直等待结果,异步就是应用程序先去做其他事,等待内核程序

根据调用者(client)的影响分为 :阻塞和非阻塞。

两类情况总共组合出5种IO模型:

先看阻塞IO

当有多个客户端都发来数据,由于都建立好了socket连接 由于应用程序在第一个client发起read调用的时候已经阻塞等待结果(recvFrom(block)),那么就无法处理第二个client的socket发来的数据流,也就是一个线程只能接收一个client的处理,一个处理完了才能处理下一个。

在这里插入图片描述

非阻塞IO

在这里插入图片描述

对于一个线程来说

是一个循环发起accprt()和read()的方法accpt和read()方法都不会阻塞,这样应用程序维护了一个

非阻塞IO太消耗CPU了 不断轮询socket

Java中的NIO没有采用非阻塞IO 而是采用IO多路复用

由eopll函数去监听多个socket 那个有数据流请求 ,对于应用程序的线程来说,多路复用器Selector 调用select()其实就是调用OS中的eopll()方法以及从数据从内核空间拷贝到用户空间仍然是阻塞,但是对于客户端来说是非阻塞的,只需要把socket个epoll去监听即可

结合代码看更方便

在这里插入图片描述

所有的事件都抽象成selectionsKey

重点就是在事件轮询器selector(多路复用器)和事件上 这样一个线程通过selector就能监听多个客户单的连接,这样相比bio,大大降低了服务端面对并发请求的开销,也即是IO多路复用的含义

在这里插入图片描述

在这里插入图片描述

但此时 这种nio编程的方式还是有缺陷

在这里插入图片描述

如果去遍历事件 然后去处理,如果有一个业务数据拷贝事件过长了怎么办?解决方法也很简单,将handle多开一个工作线程去处理,于是引出了Reactor模型,详见

事件分发器之Reactor模式详细解读

最后关于epoll函数可以参考这篇文章,讲的非常好

https://zhuanlan.zhihu.com/p/63179839

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值