Java有哪三种IO模型

  介绍

这篇文章主要为大家展示了Java有哪三种IO模型,内容简而易懂,希望大家可以学习一下,学习完之后肯定会有收获的,下面让小编带大家一起来看看吧。

Java中IO的模型分为三种,同步阻塞的生物,同步非阻塞的NIO,异步非阻塞的AIO。

<强>生物【同步阻塞】

在JDK1.4出来之前,我们建立网络连接的时候采用生物模式,需要先在服务端启动一个考察一下,然后在客户端启动插座来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。

<强> NIO【同步非阻塞】

NIO本身是基于事件驱动思想来完成的,其主要想解决的是生物的大并发问题:在使用同步I/O的网络应用中,如果要同时处理多个客户端请求,或是在客户端要同时和多个服务器进行通讯,就必须使用多线程来处理,也就是说,将每一个客户端请求分配给一个线程来单独处理。这样做虽然可以达到我们的要求,但同时又会带来另外一个问题。由于每创建一个线程,就要为这个线程分配一定的内存空间(也叫工作存储器),而且操作系统本身也对线程的总数有一定的限制。如果客户端的请求过多,服务端程序可能会因为不堪重负而拒绝客户端的请求,甚至服务器可能会因此而瘫痪。

NIO基于反应堆,当插座有流可读或可写入套接字时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。

生物与NIO一个比较重要的不同,是我们使用生物的时候往往会引入多线程,每个连接一个单独的线程;而NIO则是使用单线程或者只使用少量的多线程,每个连接共用一个线程。

NIO的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,所以所有的连接只需要一个线程就可以搞的定,当这个线程中的多路复用器进行轮询的时候,发现连接上有请求的话,才开启一个线程进行处理,也就是一个请求一个线程模式。

在NIO的处理方式中,当一个请求来的话,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,当并发上来的话,还是会有生物一样的问题。

HTTP/1.1出现后,有了HTTP长连接,这样除了超时和指明特定关闭的HTTP头外,这个链接是一直打开的状态的,这样在NIO处理中可以进一步的进化,在后端资源中可以实现资源池或者队列,当请求来的话,开启的线程把请求和请求数据传送给后端资源池或者队列里面就返回,并且在全局的地方保持住这个现场(哪个连接的哪个请求等),这样前面的线程还是可以去接受其他的请求,而后端的应用的处理只需要执行队列里面的就可以了,这样请求处理和后端应用是异步的。当后端处理完,到全局地方得到现场,产生响应,这个就实现了异步处理。

<强> AIO【异步非阻塞】

与NIO不同,当进行读写操作时,只须直接调用API的读或写方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入读方法的缓冲区,并通知应用程序,对于写操作而言,当操作系统将写方法传递的流写入完毕时,操作系统主动通知应用程序。即可以理解为,读/写方法都是异步的,完成后会主动调用回调函数。在JDK1.7中,这部分内容被称作NIO . 2,主要在java.nio.channels包下增加了下面四个异步通道:

AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel

其中的读/写方法,会返回一个带回调函数的对象,当执行完读/写取入操作后,直接调用回调函数。

    <李>生物是一个连接一个线程。 <李> NIO是一个请求一个线程。 <李> AIO是一个有效请求一个线程。
      李,

先来个例子理解一下概念

以银行取款为例:

    <李> * *同步:* *自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写), <李> * *异步:* *委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给操作系统处理,需要将数据缓冲区地址和大小传给操作系统(银行卡和密码),操作系统需要支持异步IO操作API);

    Java有哪三种IO模型