Merge pull request #78 from GungnirLaevatain/patch-1

fix typo in 把被说烂的BIO、NIO、AIO再从头到尾扯一遍.md
pull/81/head
Yang Libin 4 years ago committed by GitHub
commit 293cba2366
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,7 +4,7 @@
#### 1、流的概念和作用 #### 1、流的概念和作用
**流**:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。<Thinking in Java> **流**:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象。&lt;Thinking in Java&gt;
**流的本质**:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 **流的本质**:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
**流的作用**:为数据源和目的地建立一个输送通道。 **流的作用**:为数据源和目的地建立一个输送通道。
Java 中将输入输出抽象称为流,就好像水管,将两个容器连接起来。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流。 Java 中将输入输出抽象称为流,就好像水管,将两个容器连接起来。流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流。
@ -37,7 +37,7 @@ BIO 中的阻塞,就是阻塞在 2 个地方:
![avatar](../../../images/Netty/非阻塞IO模型.png) ![avatar](../../../images/Netty/非阻塞IO模型.png)
每次应用进程询问内核是否有数据报准备好,当有数据报准备好时,就进行拷贝数据报的操作,从内核拷贝到用户空间,和拷贝完成返回的这段时间,应用进程是阻塞的。但在没有数据报准备好时,并不会阻塞程序,内核直接返回未准备就绪的信号,等待应用进程的下一个轮寻。但是,轮寻对于 CPU 来说是较大的浪费,一般只有在特定的场景下才使用。 每次应用进程询问内核是否有数据报准备好,当有数据报准备好时,就进行拷贝数据报的操作,从内核拷贝到用户空间,和拷贝完成返回的这段时间,应用进程是阻塞的。但在没有数据报准备好时,并不会阻塞程序,内核直接返回未准备就绪的信号,等待应用进程的下一个轮询。但是,轮询对于 CPU 来说是较大的浪费,一般只有在特定的场景下才使用。
Java 的 NIO 就是采用这种方式,当我们 new 了一个 socket 后我们可以设置它是非阻塞的。比如: Java 的 NIO 就是采用这种方式,当我们 new 了一个 socket 后我们可以设置它是非阻塞的。比如:
@ -52,7 +52,7 @@ serverSocketChannel.configureBlocking(false);
上面的代码是设置 ServerSocketChannel 为非阻塞SocketChannel 也可以设置。 上面的代码是设置 ServerSocketChannel 为非阻塞SocketChannel 也可以设置。
从图中可以看到,当设置为非阻塞后,我们的 socket.read()方法就会立即得到一个返回结果(成功 or 失败),我们可以根据返回结果执行不同的逻辑,比如在失败时,我们可以做一些其他的事情。但事实上这种方式也是低效的,因为我们不得不使用轮询方法一直问 OS“我的数据好了没啊”。 从图中可以看到,当设置为非阻塞后,我们的 socket.read()方法就会立即得到一个返回结果(成功 or 失败),我们可以根据返回结果执行不同的逻辑,比如在失败时,我们可以做一些其他的事情。但事实上这种方式也是低效的,因为我们不得不使用轮询方法一直问 OS“我的数据好了没啊”。
**NIO 不会在 recvfrom询问数据是否准备好时阻塞但还是会在将数据从内核空间拷贝到用户空间时阻塞。一定要注意这个地方Non-Blocking 还是会阻塞的。** **NIO 不会在 recvfrom询问数据是否准备好时阻塞但还是会在将数据从内核空间拷贝到用户空间时阻塞。一定要注意这个地方Non-Blocking 还是会阻塞的。**
@ -60,7 +60,7 @@ serverSocketChannel.configureBlocking(false);
![avatar](../../../images/Netty/IO复用模型.png) ![avatar](../../../images/Netty/IO复用模型.png)
传统情况下 client 与 server 通信需要 3 个 socket(客户端的 socket服务端的 serversocket服务端中用来和客户端通信的 socket),而在 IO 多路复用中,客户端与服务端通信需要的不是 socket而是 3 个 channel通过 channel 可以完成与 socket 同样的操作channel 的底层还是使用的 socket 进行通信,但是多个 channel 只对应一个 socket(可能不只是一个,但是 socket 的数量一定少于 channel 数量),这样仅仅通过少量的 socket 就可以完成更多的连接,提高了 client 容量。 传统情况下 client 与 server 通信需要 3 个 socket(客户端的 socket服务端的 server socket服务端中用来和客户端通信的 socket),而在 IO 多路复用中,客户端与服务端通信需要的不是 socket而是 3 个 channel通过 channel 可以完成与 socket 同样的操作channel 的底层还是使用的 socket 进行通信,但是多个 channel 只对应一个 socket(可能不只是一个,但是 socket 的数量一定少于 channel 数量),这样仅仅通过少量的 socket 就可以完成更多的连接,提高了 client 容量。
其中,不同的操作系统,对此有不同的实现: 其中,不同的操作系统,对此有不同的实现:
@ -447,6 +447,6 @@ JDK1.7 升级了 NIO 类库,升级后的 NIO 类库被称为 NIO 2.0。Java
异步通道获取获取操作结果方式: 异步通道获取获取操作结果方式:
1. 使用 java.util.concurrent.Future 类表示异步操作的结果; 1. 使用 java.util.concurrent.Future 类表示异步操作的结果;
2. 在执行异步操作的时候传入一个 java.nio.channels操作完成后回调 CompletionHandler 接口的实现类。 2. 在执行异步操作的时候传入一个 java.nio.channels操作完成后回调 CompletionHandler 接口的实现类。
NIO 2.0 的异步套接字通道是真正的异步非阻塞 I/O对应于 UNIX 网络编程中的事件驱动 I/OAIO NIO 2.0 的异步套接字通道是真正的异步非阻塞 I/O对应于 UNIX 网络编程中的事件驱动 I/OAIO

Loading…
Cancel
Save