AI智能
改变未来

一文带你搞懂BIO、NIO和AIO


1、

Java BIO

1.1、基本介绍

Java BIO

: 同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。

1)

Java BIO

就是传统的

java io

编程,其相关的类和接口在

java.io

2)

BIO

(

blocking I/O

) : 同步阻塞**,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制改善(实现多个客户连接服务器);

3)

BIO

方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,

JDK1.4

以前的唯一选择,程序简单易理解。

1.2、

BIO

工作机制

BIO

编程简单流程

  • 服务器端启动一个

    ServerSocket

  • 客户端启动

    Socket

    对服务器进行通信,默认情况下服务器端需要对每个客户建立一个线程与之通讯;

  • 客户端发出请求后, 先咨询服务器是否有线程响应,如果没有则会等待,或者被拒绝;

  • 如果有响应,客户端线程会等待请求结束后,在继续执行。

1.3、案例

实例说明:

  1. 使用
    BIO

    模型编写一个服务器端,监听

    6666

    端口,当有客户端连接时,就启动一个线程与之通讯。

  2. 要求使用线程池机制改善,可以连接多个客户端.
  3. 服务器端可以接收客户端发送的数据(
    telnet

    方式即可)。

package com.dult;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class BIOServer {public static void main(String[] args) throws Exception {//线程池机制//思路//1. 创建一个线程池//2. 如果有客户端连接,就创建一个线程,与之通讯(单独写一个方法)ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();//创建 ServerSocketServerSocket serverSocket = new ServerSocket(6666);System.out.println(\"服务器启动了\");while (true) {System.out.println(\" 线 程 信 息 id =\" + Thread.currentThread().getId() + \" 名 字 =\" +Thread.currentThread().getName());//监听,等待客户端连接System.out.println(\"等待连接....\");final Socket socket = serverSocket.accept();System.out.println(\"连接到一个客户端\");//就创建一个线程,与之通讯(单独写一个方法)newCachedThreadPool.execute(new Runnable() {public void run() { //我们重写//可以和客户端通讯handler(socket);}});}}//编写一个 handler 方法,和客户端通讯public static void handler(Socket socket) {try {System.out.println(\" 线 程 信 息 id =\" + Thread.currentThread().getId() + \" 名 字 =\" +Thread.currentThread().getName());byte[] bytes = new byte[1024];//通过 socket 获取输入流InputStream inputStream = socket.getInputStream();//循环的读取客户端发送的数据while (true) {System.out.println(\" 线 程 信 息 id =\" + Thread.currentThread().getId() + \" 名 字 =\" +Thread.currentThread().getName());System.out.println(\"read....\");int read = inputStream.read(bytes);if(read != -1) {System.out.println(new String(bytes, 0, read)); //输出客户端发送的数据} else {break;}}}catch (Exception e) {e.printStackTrace();}finally {System.out.println(\"关闭和 client 的连接\");try {socket.close();}catch (Exception e) {e.printStackTrace();}}}}

1.4、

Java BIO

的问题分析

  • 每个请求都需要创建独立的线程,与对应的客户端进行数据

    Read

    ,业务处理,数据

    Write

  • 当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大;

  • 连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在

    Read

    操作上,造成线程资源浪费。

2、

NIO

2.1、概述

Java NIO

同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有

I/O

请求就进行处理 。

Java NIO

全称

java non-blocking IO

,是指

JDK

提供的新

API

NIO

相关类都被放在

java.nio

包及子包下,并且对原

java.io

包中的很多类进行改写。与传统

IO

区别:

2.2、

NIO

BIO

的比较

IO
NIO
面向流 面向缓冲区(或者说面向块)
阻塞IO 非阻塞IO
选择器
  • BIO

    以流的方式处理数据,而

    NIO

    以块的方式处理数据,块

    I/O

    的效率比流

    I/O

    高很多

  • BIO

    是阻塞的,

    NIO

    则是非阻塞的

  • BIO

    基于字节流和字符流进行操作,而

    NIO

    基于

    Channel

    (通道)和

    Buffer

    (缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

    Selector

    (选择器)用于监听多个通道的事件(比如:连接请求,数据到达等),因此使用单个线程就可以监听多个客户端通道 。

NIO

有三大核心部分:

Channel

( 通道) ,

Buffer

( 缓冲区),

Selector

( 选择器),之后会从源码级别细讲。

当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情,当数据被写入缓冲区时,线程可以继续处理它,从缓冲区写入通道也类似。

​ 通俗理解:

NIO

是可以做到用一个线程来处理多个操作的。假设有

10000

个请求过来,根据实际情况,可以分配

50

或者

100

个线程来处理。不像之前的阻塞

IO

那样,非得分配

10000

个。
​ 而且

HTTP2.0

使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比

HTTP1.1

大了好几个数量级。

3、

Java AIO

Java AIO

(

NIO.2

) : 异步非阻塞

AIO

引入异步通道的概念,采用了

Proactor

模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用。

  • JDK 7

    引入了

    Asynchronous I/O

    ,即

    AIO

    。在进行

    I/O

    编程中,常用到两种模式:

    Reactor

    Proactor

    Java

    NIO

    就是

    Reactor

    ,当有事件触发时,服务器端得到通知,进行相应的处理;

  • AIO

    NIO2.0

    ,叫做异步不阻塞的

    IO

    AIO

    引入异步通道的概念,采用了

    Proactor

    模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用。

4、

BIO

NIO

BIO

的比较

BIO NIO AIO
IO 模型 同步阻塞 同步非阻塞(多路复用) 异步非阻塞
编程难度 简单 复杂 复杂
可靠性
吞吐量

举例说明

1)同步阻塞:到理发店理发,就一直等理发师,直到轮到自己理发;

2)同步非阻塞:到理发店理发,发现前面有其它人理发,给理发师说下,先干其他事情,一会过来看是否轮到自己;

3)异步非阻塞:给理发师打电话,让理发师上门服务,自己干其它事情,理发师自己来家给你理发。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 一文带你搞懂BIO、NIO和AIO