Java世界里的BIO,NIO,AIO

Posted 董广明

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java世界里的BIO,NIO,AIO相关的知识,希望对你有一定的参考价值。

  作为一名程序员,io知识是必不可少,其实一直在和io打交道,要么显示要么隐含给了操作系统,故做下关于io的记录。说io之前呢,先介绍什么叫同步异步丶阻塞非阻塞

1.  同步异步丶阻塞非阻塞

1.1 同步是指发出一个请求,在没有得到结果之前该请求就不返回结果,请求返回时,也就得到结果了。比如我经常用烧水壶烧水,没烧开前一直盯着水壶(等水开)。

1.2 异步是指发出一个请求后,立刻得到了回应,但没有返回结果,这时我们可以再处理别的事情(发送其他请求),所以这种方式需要我们通过状态主动查看是否有了结果, 或者可以设置一个回调来通知调用者。比如烧水时,不需要盯着水壶等水开,也可以做别的事:玩电脑,每两三分钟(类似轮询任务)看看水开了没有,也可以给水壶设置响铃(信号通知,发邮件发短信),水开了通知了我(don’t call me,I call you)。

1.3  阻塞是指请求结果返回之前,当前线程会被挂起(被阻塞),线程什么也做不了了,而非阻塞是指请求结果返回之前,当前线程没有被阻塞,仍然可以做其他事情。

2.  IO模型

一个io请求读操作,数据会先被拷贝到操作系统内核的缓冲区中,然后从操作系统内核的缓冲区拷贝到应用程序的地址空间,所以整个过程可分为两个阶段:等待I/O数据准备好,这取决于IO目标返回数据的速度, 如网络IO时看网速和数据本身的大小;数据从内核缓冲区拷贝到进程内。

模型分类可分为以下几种:BIO,NIO,IO多路复用,AIO,我就一一简单介绍下

2.1  BIO

BIO,全称是Blocking I/O,中文名叫:阻塞 I/O,整个过程如图:

技术图片

应用程序发送请求给内核,然后由内核去进行通信,在内核准备好数据之前这个线程是被挂起的,所以在两个阶段程序都处于挂起状态, 其 特点就是在IO执行的两个阶段都被block了 。

2.2 NIO

NIO,全称是Non-Blocking    IO,中文名字叫非阻塞IO,过程如图示:

技术图片

发起第一次请求后,线程并没有被阻塞,它反复检查数据是否准备好,把原来大块不能用的阻塞时间分成了许多“小阻塞”(检查),所以进程不断有机会被执行。这个检查有没有准备好数据的过程有点类似于“轮询”。其特点就是程序需要不断的主动询问内核数据是否准备好。第一个阶段非阻塞,第二个阶段阻塞。

2.3  IO多路复用(重点,此模型不少中间件都用到了)

IO多路复用(I/O Multiplexing)有selectpollepoll等不同方式,它的优点在于单个线程可以同时处理多个网络IO。不同于NIO中轮询操作是用户线程进行的,而IO多路复用调用操作系统级别的selectpoll或epoll模型,由系统进行监控IO状态。select轮询可以监控许多socket的IO请求,当有一个socket的数据准备好时就可以返回。多路复用IO过程图:

技术图片

与NIO不同的是,select不是等到所有数据准备好才返回,而是只要有一个准备好就返回,它的强项在于可以同时处理多个连接。 其 特点是用户进程能同时等待多个IO请求,系统来监控IO状态,其中的任意一个进入读就绪状态,select函数就可以返回。 nio在java1.4才引入技术图片

2.4  AIO

AIO全称是Asynchronous I/O,中文名叫:异步 I/O,它是Java1.7 才引入。整个过程中,用户线程发起一个系统调用之后无须等待,可以处理别的事情。由操作系统等待接收内容,接收后把数据拷贝到用户进程中,最后通知用户程序已经可以使用数据了,两个阶段都是非阻塞的。整个过程如下图

技术图片

Java中可通过以下两种方式实现:

一种是基于”回调”,我们可以实现CompletionHandler接口,在调用时把回调函数传递给对应的API即可;

一种是返回一个Future。处理完别的事情,可以通过isDone()可查看是否已经准备好数据,通过get()方法等待返回数据。

好了,暂且就写这么多,多多交流探讨

参考:

1.  OReilly.Java.I.O.2nd.Edition.May.2006

2.   Unix网络编程卷1(几种io模型)

以上是关于Java世界里的BIO,NIO,AIO的主要内容,如果未能解决你的问题,请参考以下文章

也谈BIO | NIO | AIO (Java版--转)

Java BIO与NIO以及AIO分析

BIO,NIO,AIO详解

JAVA 中BIO,NIO,AIO的理解

Netty系列:基础篇 BIO-NIO-AIO

JAVA中的BIO,NIO,AIO