1.java IO模型(BIO,NIO,AIO)

【README】

本文介绍了 3种 java io模型,包括 BIO,NIO, AIO;

IO模型名称

描述

工作原理

BIO-Blocking IO

同步并阻塞式IO

一个服务器线程处理一个客户端连接

NIO-Non-blocking IO

同步非阻塞式IO

一个服务器线程处理多个客户端连接,使用io多路复用(选择器);

AIO-Asynchronous IO

异步非阻塞式IO


【1】应用场景

  • 1)BIO方式:适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序简单易理解。
  • 2)NIO方式:适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,弹幕系统,服务器间通讯等。编程比较复杂,JDK1.4开始支持。 (Netty是基于NIO的)
  • 3) AIO方式:适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。(不常用)

【1.1】BIO代码实现

1)服务端:

/**
 * @Description 阻塞式IO服务器
 * @author xiao tang
 * @version 1.0.0
 * @createTime 2022年08月13日
 */
public class BIOServer {
    public static void main(String[] args) throws IOException {
        // 创建一个线程池
        ExecutorService threadPool = Executors.newCachedThreadPool();
        int order = 0;

        // 创建 服务器 套接字
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服务器启动成功.");
        while(true) {
            System.out.println("等待客户端请求");
            Socket socket = serverSocket.accept(); // 没有客户端请求,accept阻塞
            System.out.printf("客户端[%d]请求建立连接\n", ++order);
            final int orderCopy = order;
            threadPool.execute(()->{
                handler(socket, orderCopy);
            });
        }
    }

    /**
     * @description 与客户端通讯
     * @param socket 连接套接字
     * @author xiao tang
     * @date 2022/8/13
     */
    public static void handler(Socket socket, int order) {
        byte[] byteArr = new byte[1024];

        try {
            // 读取客户端发送的数据
            InputStream inputStream = socket.getInputStream();
            int length = 0;
            // 客户端没有数据,read阻塞
//            while( ( length = inputStream.read(byteArr))!= -1) {
//                System.out.println(new String(byteArr, 0, length));
//            }
            while(true) {
                System.out.printf("线程id[%s],等待客户端[%d]发送数据\n", Thread.currentThread().getId(), order);
                length = inputStream.read(byteArr);
                if (length == -1) break;
                System.out.printf("线程id[%s],客户端[%d]:" + new String(byteArr, 0, length) + "\n",  Thread.currentThread().getId(), order);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭与客户端的连接
            try {
                socket.close();
                System.out.printf("关闭与客户端[%d]的连接\n", order);
            } catch (IOException e) {
            }
        }
    }
}

2)客户端 :采用 win10的命令行 telnet 进程;

  • 命令行录入  telnet 127.0.0.1 6666
  • 录入 ctrl + ] 进入telnet命令行界面
  • send hello100 就把hello100 发送给服务器

发送过程如下:

 【小结】

  • 显然,在BIO-阻塞式IO模式下,服务器的一个线程处理一个客户端请求;且存在阻塞情况,在客户端数量过多的情况下,性能不高(因为客户端一直挂起,则过多的服务器线程会一直阻塞,浪费大量cpu和内存资源
  • serverSocket.accept() 在没有客户端请求时,会阻塞
  • inputStream.read(...) 在客户端没有发送数据时,会阻塞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值