IO通信模型

一、我们回顾一下传统的HTTP服务器的原理

1. 创建一个ServerSocket,监听并绑定一个端口

2. 一系列客户端来请求这个端口

3. 服务器使用Accept,获得一个来自客户端的Socket连接对象

4. 启动一个新线程处理连接

  • 读Socket,得到字节流
  • 解码协议,得到Http请求对象
  • 处理Http请求,得到一个结果,封装成一个HttpResponse对象
  • 编码协议,将结果序列化字节流
  • 写Socket,将字节流发给客户端

5.继续循环步骤3

ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out =new PrintWriter(clientSocket.getOutputStream(), true);
String request, response;
while ((request = in.readLine()) != null) {
    if ("Done".equals(request)) {
        break;
}
response = processRequest(request);
out.println(response);
}

HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是WebSocket,那它就成了WebSocket服务器,等等。

使用Netty你就可以定制编解码协议,实现自己的特定协议的服务器。

上面我们说的是一个传统的多线程服务器,这个也是Apache处理请求的模式。在高并发环境下,线程数量可能会创建太多,操作系统的任务调度压力大,系统负载也会比较高。

于是NIO诞生了,NIO并不是Java独有的概念,NIO代表的一个词汇叫着IO多路复用。它是由操作系统提供的 系统调用,早期这个操作系统调用的名字是select,但是性能低下。后来渐渐演化成了Linux下的epoll和Mac里的kqueue。

而Netty就是基于Java NIO技术封装的一套框架。为什么要封装,因为原生的Java NIO使用起来没那么方便,而且还有臭名昭著的bug,Netty把它封装之后,提供了一个易于操作的使用模式和接口,用户使用起来也就便捷多了。

 

二、同步与异步,阻塞与非阻塞

同步与异步:针对多个任务而言,指的是多个任务之间的执行顺序关系

 同步:如果有多个任务或者事件要发生,这些任务或者事件必须逐个地进行,一个事件或者任务的执行会导致整个流程的暂时等待,这些事件没有办法并发地执行;

   异步:如果有多个任务或者事件发生,这些事件可以并发地执行,一个事件或者任务的执行不会导致整个流程的暂时等待。

多线程就是实现异步的一个方式,它把"第二件任务"交给其他的线程去做了。而实际上,多线程的实现原理,其本质上同一时间内,CPU只能处理1条线程,只有1条线程在工作(执行);多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)。如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。(多核处理器除外~~~)

 

阻塞与非阻塞:针对单个任务而言,指的是任务执行过程

任务在执行的过程中,由于资源不足,比如在IO操作过程中,内核进行数据拷贝的过程会停滞阻塞当前任务,而处在一种等待的状态,是阻塞。阻塞状态会一直等待到资源等满足后再执行并返回。非阻塞是指,如果资源满足则进行,如果资源不满足,则返回一个执行不成功的信息,并不等待。

阻塞与非阻塞表述了一个任务在处理问题时的不同状态,是一个点的概念,在任务达到那个点时,根据阻塞或非阻塞进行不同操作。而同步与异步是段的概念,如果是同步则这段程序将在主线程执行,如果是异步则类似多线程的行为。

 

三、IO通信的异步同步,阻塞非阻塞

IO通信主要包括:对外部设备的读写、对磁盘内容的读写、socket的读写等操作。这些操作主要分为两个部分:

1)等待IO设备响应任务
2)从IO设备处读取或向IO设备中写入内容

这两个操作都涉及到阻塞或非阻塞概念。
对于阻塞IO而言,等待IO设备响应时会一直等待它直到响应或超时为止。对于非阻塞IO而言,等待IO设备响应时如果发现它不能及时响应则会返回一个未响应信息。

第二步根据情况分为同步与异步两种概念,如果任务程序主动去内核读取或写入数据,在未完成之前,不会产生响应,主线程因此停滞则为同步IO。

而异步IO是由内核进程引导,收到IO请求后,会直接返回一个标记,主线程不阻塞可以进行其他任务,当内核进行完成了第二部的读写操作,会根据之前的标记把最后的结果返回给主线程,整个读写过程不是在用户线程上进行,而是在内核上完成,用户进程最后得到通知,这种IO通信叫做异步IO。

在同步IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。而异步IO方式中,线程发送一个IO请求到内核,然后继续处理其他的事情,内核完成IO请求后,将会通知线程IO操作完成了。

同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成

 

四、五类IO模型

推荐文章https://www.cnblogs.com/niumoo/p/9839741.html

该作者有详细的一系列文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值