• 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(...) 在客户端没有发送数据时,会阻塞

  • 相关阅读:
    OpenFeign快速入门及使用
    5年测试经验要个20K不过分吧,谁料面试官三个问题把我打发走了···
    【Kafka】(1)基础知识汇总
    python type hint
    ARM Codec要求
    样品制备丨艾美捷蛋白质羰基比色测定试剂盒方案
    专业英语历年题
    F#奇妙游(31):数据缺失的处理
    win server 2012 r2 部署 netcore 站点 500.19
    mysql执行计划explain
  • 原文地址:https://blog.csdn.net/PacosonSWJTU/article/details/126320985