美文网首页
Java IO使用的四种模式

Java IO使用的四种模式

作者: Java架构小喳喳 | 来源:发表于2019-03-14 11:55 被阅读0次

对于Java IO,从大的种类上来分,可以分为BIO和NIO。BIO全称为Blocked IO,也即阻塞型IO,而NIO则是在jdk 1.4中引入的,一般称其为New IO,因为这是相对于1.4版本之前的阻塞型IO而言的,但是也有人称其为Non-blocked IO。相对而言,本人更喜欢第二种叫法,因为从字面上更符合其使用含义。本文则主要基于BIO和NIO讲解四种IO模式的基本使用方式,并且对这四种模式的优缺点进行对比。

最基本的BIO使用方式就是同步SocketChannel的方式,我们这里以经典的EchoClient/EchoServer模式来对其进行讲解,如下是一个示例:

这里可以看到,服务端处理主要是首先开启一个ServerSocketChannel,然后在一个无限循环中不断获取客户端连接,获取之后进行处理,并且写入响应信息。下面我们看看客户端代码:

如下分别是服务端和客户端打印的数据:

可以看到,服务端和客户端都正常接收并且处理了对方的数据。关于同步BIO模式,这里主要存在以下几个问题:

上述BIO模式中,最主要的问题在于服务器同一时刻只能处理一个客户端请求,这会极大的限制服务器性能。这里可以采用异步BIO的模式解决这个问题,也就是上面的服务器主线程只负责接收客户端请求,在收到请求之后将客户端请求Channel委托到一个线程池中异步进行处理。这样服务器在同一时刻就可以同时建立多个连接,极大的提升了服务器的性能。如下是EchoServer的代码:

对于客户端代码,其与同步BIO模式中的一致,这里就不再赘述。可以看到,相对于同步BIO模式,异步BIO模式改进了其主要问题,因而可以在同一时刻接收到多个客户端请求。但是对于异步BIO模式,其存在的问题也非常明显:

由于BIO存在的诸多问题,在jdk 1.4中,Java提供了一种非阻塞型的IO模型,也即NIO。NIO本质上采用的是IO多路复用模式,实际上就是一个事件驱动模型,简单的理解为一个服务器在绑定某个端口之后,其可以在一个线程了同时监听多个客户端连接,而且服务器可以对每个客户端分别设置对其哪些事件感兴趣。当客户端有对应的事件发生时,其就会通知服务器监听线程,服务器线程监听到对应的事件之后,其就会将其交由线程池处理对应的事件。实际上,Java的NIO模式在底层也是依赖于操作系统的多路复用模型,对于Linux系统,其底层是使用epoll模型实现的,而对于Mac os,其则是使用kqueue模型实现的。如下是一个IO多路复用的示意图:

这里的Selector就可以理解为一个多路复用器,每个客户端连接就是一个SocketChannel,这些SocketChannel会在Selector上注册,并且设置对各个Channel感兴趣的事件。当Selector监听到对应的事件之后,其就会将事件交由下层的线程处理。如下是一个使用NIO处理客户端事件的示例:

在上述代码中,我们首先创建了一个ServerSocketChannel,并且通过其*configureBlocking()*方法将其设置为非阻塞模式,设置为这种模式之后,其accept()等方法就是非阻塞的。然后我们创建了一个Selector多路复用器,并且将ServerSocketChannel注册到该多路复用器上。接着通过多路复用器的select()方法阻塞当前线程,等待注册的Channel事件触发。在触发之后通过遍历SelectionKey对象来进行不同事件的处理。下面我们来看看使用Java NIO来实现客户端的代码:

这里客户端的处理模式与服务端基本类似,只是客户端首先监听的是Connect事件;在连接成功后切换为监听写入事件,以写入数据发送到服务端;在发送完成后,又会切换为监听读取事件,以等待服务器发送数据并且进行处理。这里NIO模式相对于BIO主要有以下几个优点:

对于AIO模式,其是在jdk 1.7中加入的,主要原因是NIO模式代码编写非常复杂,并且容易出错。AIO本质上还是使用的NIO的多路复用来实现的,只不过在模型上其使用的是一种事件回调的方式处理各个事件,这种方式更加符合NIO异步模型的概念,并且在编码难易程度上比NIO要小很多。

在AIO中,所有的操作都是异步执行的,而每个事件都是通过一个回调函数来进行的,这里也就是一个CompletionHandler对象。这里我们以EchoClient和EchoServer为例看一下AIO模式的使用方式:

对于上述的AIO模式服务端的代码编写,可以看出来,AIO模式完全是基于异步线程池处理客户端事件的,而且对于每个事件的处理,其都是通过一个CompletionHandler进行处理的。对于服务端而言,其首先通过AcceptCompletionHandler处理的是accept事件,处理完成之后就监听客户端的read事件,然后通过ReadCompletionHandler处理客户端的数据读入事件;最后通过一个内部类(本质上也是一个CompletionHandler)往客户端写入数据。下面我们看一下客户端代码:

可以看到,客户端的处理方式与服务端基本类似,首先是连接服务器。连接完成后,通过ConnectionCompletionHandler进行后续处理,这里首先是异步往服务器写入数据,写入完成后监听服务器的数据响应,最后读取服务器数据并打印。可以看到AIO模式相较于NIO有如下优点:

本文主要基于BIO和NIO讲解了Java IO的四种编码模式,并且循序渐进讲解了每种编码模式的基本使用方式和优缺点。

相关文章

  • Java IO使用的四种模式

    对于Java IO,从大的种类上来分,可以分为BIO和NIO。BIO全称为Blocked IO,也即阻塞型IO,而...

  • tomcat的线程配置

    首先,这和tomcat的使用的IO模式有关 关于Java IO模式、以及IO处理的线程模型等基础的通信框架的知识,...

  • Java中的IO模型

    Java中的IO模型 Java中的IO模型有四种: 同步阻塞IO 同步非阻塞IO IO多路复用 异步IO 其中IO...

  • Java IO小小的心得

    学习JAVA IO之前必须要先学习装饰模式 上面是Java中创建一个文件对象的语句,Java在IO库的设计中使用了...

  • tomcat的线程模型

    四种线程模型BIO:阻塞式IO,采用传统的java IO进行操作,该模式下每个请求都会创建一个线程,适用于并发量小...

  • 让你再也忘不了IO相关知识-Java IO图文详解

    1 装饰模式 Java中IO使用的是装饰模式,装饰模式在Android中很常见,比如系统的Context。 装饰模...

  • Tomcat性能调优

    一、Tomcat三种运行模式选择 1、bio模式 性能最差不推荐使用 2、nio模式(优先) (1)java IO...

  • JAVA IO基础知识

    JAVA IO流采用的是装饰器设计模式,通过IO操作可以完成对特定设备进行数据的读写操作,深入理解IO的设计和使用...

  • Java四种单例设计模式

    Java中的四种单例模式 单例模式是最容易理解的设计模式之一,介绍Java中单例模式的四种写法。 1.基本单例模式...

  • 梳理二

    1、java四种引用类型 https://longfeizheng.github.io/2018/04/09/Ja...

网友评论

      本文标题:Java IO使用的四种模式

      本文链接:https://www.haomeiwen.com/subject/fjdqmqtx.html