当前位置: 首页 > 科技观察

这篇JavaNIO编程,保证你能看懂

时间:2023-03-19 23:35:44 科技观察

NIO编程,一直是Java知识体系中的重点。前几年面试的门槛是懂NIO,现在不一样了,至少要精通NIO,所以学习javaNIO编程是很有必要的。本文从对NIO的了解开始。本文参考MOOC,特此说明。1、认识NIO1,什么是BIO?如果要学习NIO,那么首先要了解BIO。在JDK1、4之前,我们在使用网络连接,也就是阻塞的时候,总是使用BIO,网络模型是这样的。上面的网络模型是这样的。(1)服务端创建并初始化一些准备工作后,开始等待客户端client的连接(2)客户端开始连接服务端。(3)服务器端一旦请求到客户端的请求,就会开启一个线程进行处理。好像只有一家餐厅。每次有客户进来,我们都需要创建一个线程来处理。这是生物。他的缺点可想而知。如果客户端很多,服务端就得开很多Thread来处理,太麻烦了。毕竟像淘宝、微信这样的平台,有上亿人在使用,这么大的请求量,不可能开上亿线程去处理。这时,JDK1.4出现了NIO。2、NIO的出现既然BIO有这么多缺点,java官方肯定也明白,所以在jdk1.4的时候及时加入了NIO。我们来看看这个和前面的区别:(1)client进来后,先加入Set(2)server一直轮询set,一旦发现有client连接上,itstartstohandle(3)Multipleclientconnectinin,storedinthisset,这样我们就可以轮询处理多个client。这就是NIO,从上图也能看出它的优势。我们可能只需要创建一个线程来处理所有客户端。当然,每个客户都有不同的事情要做。有的是连接请求,有的是读写请求。这时候服务端可以根据不同的请求使用不同的处理程序。再给一张图看看:当然,这只是罗列了NIO的特性,以及一个通用的网络模型。想要真正了解他,还是需要直接从代码中来。二、代码实现1、基本概念在正式开始编写代码之前,我们需要先熟悉一下涉及到的几个类。(1)channel相当于一个channel,这个channel就是一个数据流,我们不仅可以从channel中读取数据,还可以向channel中写入数据。常用的通道有四种:FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel。FileChannel从文件中读取和写入数据。DatagramChannel可以通过UDP在网络中读写数据。SocketChannel可以通过TCP在网络中读写数据。ServerSocketChannel可以侦听新传入的TCP连接,就像Web服务器一样。为每个新的传入连接创建一个SocketChannel。(2)BufferBuffer用于与channel进行交互。数据从通道读取到缓冲区,然后从缓冲区写入通道。使用Buffer读写数据一般分为以下四个步骤:向Buffer写入数据调用flip()方法从Buffer中读取数据调用clear()方法或compact()方法(3)SelectorSelector(选择器)可以检测一个MultipleNIOchannels,以及了解通道是否为组件(如读写事件)做好准备的能力。这样,单个线程可以管理多个通道,从而管理多个网络连接。2.实现步骤这里我们实现一个类似于聊天室的案例。上面介绍了NIO涉及的一些核心类,下面介绍实现步骤。这一步结合上图更容易理解:第一步:创建Selector第二步:创建ServerSocketChannel,绑定监听端口第三步:设置Channel为非阻塞模式第四步:注册Channel进入选择器并监听连接事件。Step5:循环调用Selector的select方法检测就绪Step6:调用selectedKeys方法获取就绪通道集合Step7:判断就绪事件类型,调用业务处理方法Step8:根据业务需要决定是否重新注册监听事件,重复第三步。这一步之后,我们就去代码中去实现它。3.代码实现(1)服务端代码开发首先我们来看一下服务端。服务器中的基本步骤如上实现。现在让我们开始吧。第一种情况:链接事件处理第二种情况:读写时间到了broadCast方法的第五步。事实上,我们可以对此做出改变。在这里,我们实现了对所有其他客户端的广播。但是如果是一对一的聊天,我们可以单播给指定的客户端。这是整个server端的开发,当然还有client端的开发,我们来看一样。(2)客户端代码开发客户端代码说实话稍微容易一点。我们来看看客户端是如何处理服务端返回的数据的。readHandler方法如何读取?至此,整个客户端代码就完成了。仔细过一遍,其实整个过程是很清楚的。3.总结NIO虽然这么好,但是它还是有很多缺点。你其实可以找出上面的代码量。大量的代码让我们在构建复杂系统的时候超级麻烦。有时是这些技术的不完善。这就造成了我们程序员的工作量大,压力大,但是科技的进步毕竟是需要一点一点发展的。另外这个NIO还有一个很大的坑,就是当Selector轮询为空的时候,tutor的CPU是100%。但是在这种情况下我还没有尝试过。如果你想精通NIO,这篇文章真的不够看,顶多是个介绍。要想真正理解,我觉得还是得先深入源码,然后在实际场景中使用。但是目前netty和mina框架比java的NIO要好很多,不仅仅是性能上,更重要的是我们的开发效率。也算是在一定程度上避免了我们程序员“钱多话少死得快”的现象。