• 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)服务端:

    1. /**
    2. * @Description 阻塞式IO服务器
    3. * @author xiao tang
    4. * @version 1.0.0
    5. * @createTime 2022年08月13日
    6. */
    7. public class BIOServer {
    8. public static void main(String[] args) throws IOException {
    9. // 创建一个线程池
    10. ExecutorService threadPool = Executors.newCachedThreadPool();
    11. int order = 0;
    12. // 创建 服务器 套接字
    13. ServerSocket serverSocket = new ServerSocket(6666);
    14. System.out.println("服务器启动成功.");
    15. while(true) {
    16. System.out.println("等待客户端请求");
    17. Socket socket = serverSocket.accept(); // 没有客户端请求,accept阻塞
    18. System.out.printf("客户端[%d]请求建立连接\n", ++order);
    19. final int orderCopy = order;
    20. threadPool.execute(()->{
    21. handler(socket, orderCopy);
    22. });
    23. }
    24. }
    25. /**
    26. * @description 与客户端通讯
    27. * @param socket 连接套接字
    28. * @author xiao tang
    29. * @date 2022/8/13
    30. */
    31. public static void handler(Socket socket, int order) {
    32. byte[] byteArr = new byte[1024];
    33. try {
    34. // 读取客户端发送的数据
    35. InputStream inputStream = socket.getInputStream();
    36. int length = 0;
    37. // 客户端没有数据,read阻塞
    38. // while( ( length = inputStream.read(byteArr))!= -1) {
    39. // System.out.println(new String(byteArr, 0, length));
    40. // }
    41. while(true) {
    42. System.out.printf("线程id[%s],等待客户端[%d]发送数据\n", Thread.currentThread().getId(), order);
    43. length = inputStream.read(byteArr);
    44. if (length == -1) break;
    45. System.out.printf("线程id[%s],客户端[%d]:" + new String(byteArr, 0, length) + "\n", Thread.currentThread().getId(), order);
    46. }
    47. } catch (IOException e) {
    48. e.printStackTrace();
    49. } finally {
    50. // 关闭与客户端的连接
    51. try {
    52. socket.close();
    53. System.out.printf("关闭与客户端[%d]的连接\n", order);
    54. } catch (IOException e) {
    55. }
    56. }
    57. }
    58. }

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

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

    发送过程如下:

     【小结】

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

  • 相关阅读:
    CSS接触
    PAM从入门到精通(二十四)
    linux rm文件后空间不释放怎么处理
    爬虫工作流程、请求与响应原理、requests库讲解
    3.8-镜像的发布
    精简版 — Hive开发常用操作
    理解 ByteBuffer
    SAP 电商云 Spartacus UI 去除 Checkout 页面 header 和 footer 区域的几种方法介绍
    this.$set用法
    微信小程序
  • 原文地址:https://blog.csdn.net/PacosonSWJTU/article/details/126320985