亲宝软件园·资讯

展开

java NIO理解分析与基本使用

数小钱钱的种花兔 人气:0
我前段时间的一篇博客[java网络编程——多线程数据收发并行](https://www.cnblogs.com/buptleida/p/12514450.html)总结了服务端与客户端之间的收发并行实践。原理很简单,就是针对单一客户端,服务端起两个线程分别负责read和write操作,然后线程保持阻塞等待读写执行。 事实上,这样的模式非常糟糕。因为每一个客户端在服务端需要占用两条线程,假如有1000个客户端,则需要2000+条线程。cpu需要花费大量的时间进行线程上下文切换,造成系统资源浪费。 想要缩减线程数量,先要解决阻塞问题。而NIO可以通过IO多路复用将read和write的阻塞给抹去。再配合线程池,即可实现用少量的线程支撑起上百万个客户端的连接。 ## 什么是NIO #### NIO与IO多路复用 java NIO全称java non-blocking IO。字面意思即非阻塞式IO。实际上这里的非阻塞只是宏观的说法。 关于IO模式,这里引一个别人的博客,介绍了几种IO模式的区别: [简述同步IO、异步IO、阻塞IO、非阻塞IO之间的联系与区别](https://www.cnblogs.com/felixzh/p/10345929.html) 本博客不再赘述这些,只是想说NIO属于其中的IO复用模型。(实验室里有一本《UNIX网络编程》疫情结束回学校一定把这部分好好看看) 多路复用IO模型中,会有一个线程去不断轮询多个socket的状态,当socket有读写事件时,才来调用IO操作。因为是一个线程来管理多个socket,系统不需要建立其它线程、维护线程,只有socket就绪时,才会使用IO资源,所以它大大降低了资源占用。 java NIO中,使用selector.select()监听多个通道是否有到达事件,没有事件就一直阻塞,有事件就调用IO进行处理。 #### 三大核心 - 通道(Channel) - 缓冲区(Buffer) - 选择器(Selectors) 详细介绍如下 ![image](http://qiniu.debrisflow.cn/20200404NIO3Bean.png) ## NIO使用举例 这里以服务端读取客户端消息的流程为例,介绍NIO的使用(完整内容只有输入,暂且不管输出)。画了一个流程图,如下所示: ![image](http://qiniu.debrisflow.cn/20200404NIORead.png) 1. 建立selector和ServerSocketChannel,并绑定注册,用于监听客户端连接请求,代码如下: ``` selector = Selector.open(); ServerSocketChannel server = ServerSocketChannel.open(); // 设置为非阻塞 server.configureBlocking(false); // 绑定本地端口 server.socket().bind(new InetSocketAddress(port)); // 注册客户端连接到达监听 server.register(selector, SelectionKey.OP_ACCEPT); ``` 同时还要建立readSelector和writeSelector。其实线程池也是提前建立的,这里暂且不写。 ``` readSelector = Selector.open(); writeSelector = Selector.open(); ``` 2. 监听通道,得到客户端,并建立SocketChannel,用于监听后续客户端消息 ``` //select()方法返回已就绪的通道数 if (selector.select() == 0) { continue; } Iterator

加载全部内容

相关教程
猜你喜欢
用户评论