BIO与NIO,AIO 总结
# BIO与NIO,AIO 总结## 1、前备知识:
### 1.1、同步与异步
- 同步:同步就是系统发起一个调用后,被调用者未处理完请求之前,调用不返回。
- 异步: 异步就是系统发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者,返回结果。
***同步和异步的最大的区别:如果是异步,调用者不需要等待处理结果,被调用者会通过回调等机制来通知调用者其返回结果。***
### 1.2、阻塞和非阻塞
- **阻塞:** 阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续。
- **非阻塞:** 非阻塞就是发起一个请求,调用者不用一直等着结果返回,继续做其他的操作。
## 2、BIO(一个连接一个线程)
### 2.1、前言
- 一般来说,BIO是采用了一个独立的 Acceptor 线程负责监听客户端的连接,如果只有一个线程,接收到一个用户请求的时候,就会建立通信套接字,并在套接字上面进行读写操作,此时是不能再接收其他客户端的请求的,也就是会导致其他的请求被挂起(阻塞)
- 想要解决这个问题,往往会采用多线程,一个线程对应一个请求,以此来打破每次只能处理一个请求的弊端。所以他要为每一个请求,都创建一个线程,处理完这个请求的事情后,线程销毁,这种模型叫做:**一请求一应答通信模型**。但是,线程的创建和销毁都特别耗费CPU的资源,如果并发量够高,系统很有可能因为无法荷载,从而导致宕(dang)机。
为了解决这个问题,引入了伪异步IO的概念。
### 2.2、伪异步IO
- 伪异步IO采用了线程池,线程池可以有效的避免大量的线程被创建和销毁的问题,同时可以设置线程池的大小,让线程处于一个固定的范围内,从而系统不会出现宕机的问题,也可以处理多个用户的请求。
### 2.3、BIO的问题
但是他的底层还是BIO模型,不能从根本上解决问题。(线程被挂起的问题),所以从jdk1.4开始,引入了NIO模型,也叫New IO 模型
## 3、NIO(一个请求一个线程)
在NIO模型中,引入了三个重要的概念----***Channel , Selector,Buffer***
### 3.1、NIO与IO的区别
#### 3.1.1、Buffer(缓冲区)
- IO是面向流的,NIO是面向Buffer的,Buffer是一个对象,他包含了一些要读入和写出的数据。
- 老的IO方式,虽然也有buffer区,但是这个Buffer区只是一个流的包装类,其实所有的操作,都是直接操作的流。
- NIO中所有的数据都是用缓冲区处理,NIO中不管是读,还是写操作,都是与Buffer(缓冲区)打交道
#### 3.1.2、Channel(通道)
这是一个双向的通道,既可以读,也可以写。而IO只能进行读或者是写。无论是读还是写操作,channel通道都是与Buffer区进行交互,且实现了异步读写!(NIO是同步非阻塞,线程是同步的,但是在遇到读操作未完成,或者写操作未完成的时候,线程不会堵塞,后面的继续运行,进行写操作,或者读操作,异步读写!)
#### 3.1.3、Selectors(选择器)
这是NIO独有的,IO要每个连接都对应一个线程。但是NIO把每个连接通过channel(连接通过Channel和selectors进行连接),连接到Selectors上进行管理(一个selectors对应有多个Channel),他只需要使用一个线程,来管理多个通道,因此只需要较少的线程来管理这些请求,从而实现了多路复用。
#### 3.1.4、非阻塞IO
正如上面所说的,IO的线程是阻塞的,NIO的线程是非阻塞的。
### 3.2、NIO问题
NIO虽然实现了同步不阻塞,但是他的线程还是同步的,在向系统发送操作指令的时候,虽然没有完成,也不会阻塞,但是他要经常向系统发送请求,询问操作是否完成,这样子也耗费了许多的资源。
其次,NIO的Selectors选择器,会轮番的对注册的通道进行轮询,查看是否有请求,这也耗费了许多资源
## 3、AIO(一个有效请求一个线程)
AIO俗称NIO2,在jdk1.7之后引入,它是异步的非阻塞IO模型。
异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程再进行后续的操作,这也就解决了NIO经常向系统询问操作是否完成的问题
AIO不常用,后面的希望有大神来补充~ 看来大家都没注意这个...我记得这个大厂面试还是挺重要的呀
页:
[1]