通过上篇博文我们已能发现 NIO 编程难度确实比同步阻塞 BIO 大很多,而且之前的 NIO 并没有考虑"半包读","半包写",如果加上这些,会更加复杂,那为什么 NIO 使用越来越广泛,它的优点如下:
-
客户端发起的连接操作是异步的,可以通过在多路复用器注册 OP_CONNECT 等待后续结果,不需要像之前的客户端那样被同步阻塞。
-
SocketChannel 的读写操作都是异步的,如果没有可读写的数据它不会同步等待,直接返回,这样 I/O 通信线程就可以处理其他的链路,不需要同步等待这个链路可用。
-
线程模型的优化:由于 JDK 的 Selector 在 Linux 等主流操作系统上通过 epoll 实现,它没有连接句柄数的限制(只受限于操作系统的最大句柄数或者对单个进程的句柄限制),这意味着一个 Selector 线程可用同时处理成千上万个客户端连接,而且性能不会随着客户端的增加而线性下降,一会那次,它非常适合做高性能、高负载的网络服务器。
JDK1.7 升级了 NIO 类库,升级后的 NIO 类库被称为 NIO2.0,引人注目的是,java 正式提供了异步文件 I/O 操作,同时提供了与 UNIX 网络编程事件驱动 I/O 对应的 AIO; 它不需要通过多路复用器 Selector 对注册的通道进行轮询操作即可实现异步读写。下面以 AIO 举例上篇文章的客户端连接服务器获取当前时间。
NIO2.0 提供了异步文件通道和异步套接字通道的实现,异步通道提供两种方式后去操作结果:
通过 java.util.concurrent.Future 类来标识异步操作的结果;
在执行异步操作的时候传入一个 java.nio.channels.
CompletionHandler 接口的实现类作为操作完成的回调。
服务端
TimeServer
.java
AcceptCompletionHandler
.java
客户端
TimeClient
.java
运行结果 Server 端
客户端:
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于