一、IO 介绍
IO的全称其实是:Input/Output的缩写
传统的 IO 大致可以分为 4种类型:
- InputStream、OutputStream 基于字节操作的 IO
- Writer、Reader 基于字符操作的 IO
- File 基于磁盘操作的 IO
- Socket 基于网络操作的 IO
IO都是依赖操作系统内核进行的,我们程序中的IO读写其实是由操作系统内核中的read&write两大系统调用。
那内核是如何进行IO交互的呢?
- 网卡收到经过网线传来的网络数据,并将网络数据写到内存中。
- 当网卡把数据写入到内存后,网卡向cpu发出一个中断信号,操作系统便能得知有新数据到来,再通过网卡中断程序去处理数据。
- 将内存中的网络数据写入到对应socket的接收缓冲区中。
- 当接收缓冲区的数据写好之后,应用程序开始进行数据处理。
对应抽象到java的socket代码简单示例如下:
public class SocketServer {
public static void main(String[] args) throws Exception {
// 监听指定的端口
int port = 8080;
ServerSocket server = new ServerSocket(port);
// server将一直等待连接的到来
Socket socket = server.accept();
// 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1) {
//获取数据进行处理
String message = new String(bytes, 0, len,"UTF-8");
}
// 省略……
}
}
看到这个过程和底层内核的网络IO很类似,主要体现在accept()等待从网络中的请求到来然后bytes[]数组作为缓冲区等待数据填满后进行处理。
而 BIO、NIO、AIO之间的区别就在于这些操作是同步还是异步,阻塞还是非阻塞。
二、同步与异步
同步 和 异步 指的是:
一个执行流程中每个方法是否必须依赖前一个方法完成后才可以继续执行。
假设我们的执行流程中:依次是方法一和方法二
- 同步指的是调用一旦开始,调用者必须等到方法调用返回后,才能继续后续的行为。
即方法二一定要等到方法一执行完成后才可以执行。
- 异步指的是调用立刻返回,调用者不必等待方法内的代码执行结束,就可以继续后续的行为。(具体方法内的代码交由另外的线程执行完成后,可能会进行回