Java BIO 和 NIO 使用,有什么区别

news2024/10/7 16:24:44

Java 中的 I/O 操作主要有两种方式:BIO 和 NIO。BIO(Blocking I/O)是同步阻塞 I/O 模型,而 NIO(Non-Blocking I/O)是异步非阻塞 I/O 模型。这两种 I/O 模型在编写网络应用程序时有着不同的优缺点,下面我们将会详细讨论它们的区别。

在这里插入图片描述

区别和模型

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

BIO

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

NIO

BIO

BIO 是 Java 最早的 I/O 模型,它是阻塞式的 I/O 模型,即在进行读写操作时,当前线程会一直阻塞,直到读写完成。BIO 通常是单线程的,也就是说一个连接需要一个线程来处理,如果连接数量很大,那么就需要创建很多线程,这样会导致系统的资源消耗过大。

下面是一个简单的 BIO 服务端代码:

public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        try {
            serverSocket = new ServerSocket(8888);
            System.out.println("服务端启动,等待客户端连接...");
            while (true) {
                socket = serverSocket.accept();
                System.out.println("客户端连接成功:" + socket.getRemoteSocketAddress());
                inputStream = socket.getInputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    System.out.println("接收到客户端消息:" + new String(buffer, 0, len));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这段代码中,我们启动了一个服务端,用于监听端口 8888,当有客户端连接时,就会创建一个新的线程处理该连接。在读取客户端发送的消息时,服务端会一直阻塞,直到读取完成,因此如果有多个连接同时发送消息,就需要创建多个线程来处理。

NIO

NIO 是 Java 1.4 引入的一种 I/O 模型,它是异步非阻塞的 I/O 模型,与 BIO 不同的是,NIO 的读写操作是非阻塞的,即读写操作不会一直阻塞当前线程,而是会立即返回,如果当前没有数据可读,或者写入的数据还没有完全被发送,就会返回 0 或者非阻塞状态,这样可以让当前线程继续执行其他任务,从而提高系统的并发能力。

下面是一个简单的 NIO 服务端代码:

public class Server {
    public static void main(String[] args) {
        ServerSocketChannel serverSocketChannel = null;
        Selector selector = null;
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(8888));
            serverSocketChannel.configureBlocking(false);
            selector = Selector.open();
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务端启动,等待客户端连接...");
            while (true) {
                int readyChannels = selector.select();
                if (readyChannels == 0) {
                    continue;
                }
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    iterator.remove();
                    if (selectionKey.isAcceptable()) {
                        ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();
                        SocketChannel socketChannel = server.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                        System.out.println("客户端连接成功:" + socketChannel.getRemoteAddress());
                    } else if (selectionKey.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(1024);
                        int len;
                        while ((len = socketChannel.read(buffer)) > 0) {
                            buffer.flip();
                            System.out.println("接收到客户端消息:" + new String(buffer.array(), 0, len));
                            buffer.clear();
                        }
                        if (len == -1) {
                            socketChannel.close();
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (serverSocketChannel != null) {
                    serverSocketChannel.close();
                }
                if (selector != null) {
                    selector.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

这段代码中,我们启动了一个 NIO 服务端,用于监听端口 8888,当有客户端连接时,就会注册一个读事件,并将其加入到选择器中。在读取客户端发送的消息时,服务端会一直读取,直到读取完成,但并不会阻塞当前线程,因此可以处理多个连接同时发送的消息。

区别

BIO 和 NIO 之间的最大区别在于阻塞和非阻塞。BIO 是阻塞式的 I/O 模型,而 NIO 是非阻塞式的 I/O 模型。BIO 通常是单线程的,一个连接需要一个线程来处理,如果连接数量很大,那么就需要创建很多线程,这样会导致系统的资源消耗过大。而 NIO 利用了选择器的概念,可以使用一个线程处理多个连接,从而提高系统的并发能力。

另外,NIO 还引入了缓冲区(Buffer)的概念,可以提高读写操作的效率。在 NIO 中,读取数据时先将数据读入到缓冲区中,然后再从缓冲区中读取数据。在写入数据时也是先将数据写入到缓冲区中,然后再从缓冲区中写出数据。

总结

BIO 和 NIO 之间的最大区别在于阻塞和非阻塞。BIO 是阻塞式的 I/O 模型,而 NIO 是非阻塞式的 I/O 模型。BIO 通常是单线程的,一个连接需要一个线程来处理,如果连接数量很大,那么就需要创建很多线程,这样会导致系统的资源消耗过大。而 NIO 利用了选择器的概念,可以使用一个线程处理多个连接,从而提高系统的并发能力。另外,NIO 还引入了缓冲区(Buffer)的概念,可以提高读写操作的效率。在使用 I/O 操作时,我们需要根据具体的业务需求选择合适的 I/O 模型,从而提高系统的性能和并发能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/539306.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Intel® ZTNA RA 23.03 release

摘要 传统的防火墙、入侵检测系统都是基于物理边界的&#xff0c;默认墙内安全&#xff0c;墙外不安全。随着应用程序和用户现在更可能在外围而不是内部&#xff0c;这种安全模型已经不再适用于当今复杂的网络场景。而“零信任”脱离了这种传统的安全模型&#xff0c;不再区别对…

论文浅尝 | 常识问答中的忠诚知识图解释

笔记整理&#xff1a;邹铭辉&#xff0c;天津大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://aclanthology.org/2022.emnlp-main.743 动机 知识图谱通常被用作常识问答的信息来源&#xff0c;同时也可以用来解释模型对答案的选择。纳入图谱中事实信息的一个常…

诺贝尔奖得主Warshel:用计算化学揭开生命底层分子运行机制|智源大会嘉宾风采...

导读 复杂化学系统的多尺度建模可以用于计算机辅助药物设计、疾病致病机制、早期诊断生物标记、创新药物开发&#xff0c;这些具有划时代意义的研究成果&#xff0c;都凝结着计算化学研究先驱Arieh Warshel夜以继日的努力。 Warshel的传奇人生始于以色列一家公社的鱼塘&#xf…

【强烈推荐】3dMax自动展UV神器UV-Packer插件

UV-Packer是一款快速、精确的UV自动展开工具。这是一个一键式的解决方安&#xff0c;可以解决将展开的多边形排序和压缩成UV片的艰巨工作。 【适用版本】 3dMax2015-2024 【主要特性】 最小的UV区域浪费 确定良好 UV 包装的第一条规则是未覆盖的 UV 区域有多少。 浪费的空间…

操作系统的发展史(DOS/Windows篇)

操作系统的最强入门科普&#xff08;Unix/Linux篇&#xff09; 上一篇文章&#xff0c;小枣君介绍了Unix和Linux操作系统的诞生和发展。今天这篇&#xff0c;我再来说说微软的DOS和Windows系列。 █ DOS操作系统 上期提到&#xff0c;20世纪70年代&#xff0c;伴随着计算机技术…

360QPaaS参编信通院《组装式应用开发平台研究报告》| 应用前沿

在数字化转型的大背景下&#xff0c;“组装式应用” 成为行业重要战略趋势之一。数字化相较于信息化&#xff0c;强调基于信息数据反哺业务&#xff0c;业务进一步促进系统的迭代优化。组装式应用平台就是一种以业务为中心的模块化组件构成。组装式应用协力提供更灵活的组装式部…

Apache Iceberg 中引入索引提升查询性能

动手点关注 干货不迷路 ‍ ‍Apache Iceberg 是一种开源数据 Lakehouse 表格式&#xff0c;提供强大的功能和开放的生态系统&#xff0c;如&#xff1a;Time travel&#xff0c;ACID 事务&#xff0c;partition evolution&#xff0c;schema evolution 等功能。 本文将讨论火山…

治病如救火,怎样让新药研发更快、更省、更准?

说起医疗与生命科学行业&#xff0c;许多人可能都会想到一句俗语——“治病如救火”&#xff0c;可见其分秒必争的时效性。 然而&#xff0c;如果与日新月异的科技行业相比&#xff0c;医疗与生命科学行业在研发上的速度则慢得惊人。来自《自然》杂志的数据显示&#xff0c;一款…

搭建企业级ESB:让接口管理高效

目 录 01 接口管理现状分析‍‍‍‍‍ 02 ESB对接口的管理‍‍‍‍‍‍ 03 ESB接口管理的发展‍‍‍‍ 04 总结 01 接口管理现状分析‍ 随着社会的发展企业中建立了许多系统&#xff0c;系统中提供了许多接口作为业务解耦的重要手段。随着业务关系越来越复杂、依赖越来越多&…

Krpano之一全景图中嵌入可闪烁的热点图片

效果 步骤 1、打开ptgui软件加载全景图 2、镜头参数设置 3、编辑全景图 4、设置编辑模式 5、拖动鼠标和划动两个方向来调整全景图范围 调整后大概是这样的,我只要在这个区域画一个面即可,尽量让调整后是俯视图,这样在这基础上画的面会比较正一些

拼多多买家如何导出“个人中心”订单信息

经常在拼多多买东西&#xff0c;有时候需要把订单的物流信息导出来&#xff0c;方便记录和统计。现介绍如何使用dumuz工具来实现批量下载拼多多订单。 应用功能描述 模拟人工操作拼多多"个人中心-我的订单”订单网页&#xff0c;批量查询获取拼多多自己买的商品的订单数…

Istio 微服务架构的演变

微服务架构的演变 单体模式下面一个应用通常会有一个app server&#xff0c;这个app server里面会有不同的子模块&#xff0c;每一个模块都写在同一个应用包里面&#xff0c;模块和模块之间的边界有些时候设计的不是特别清晰&#xff0c;特别早期代码混合在一起那么意味着互相的…

PCL学习之滤波算法

前言 点云滤波作为常见的点云处理算法&#xff0c;一般是点云处理的第一步&#xff0c;对后续处理有很重要作用。滤波 有很多方面也有很多种功能&#xff0c;比如去除噪声点、离群点、点云平滑以及空洞、数据压缩等 原始点云数据往往包含大量散列点、孤立点&#xff0c;在获取…

CS 224N总结

CS 224N网址&#xff1a;Stanford CS 224N | Natural Language Processing with Deep Learning Lecture1 PPT网址&#xff1a;PowerPoint Presentation (stanford.edu) 这一讲主要讲了NLP研究的对象&#xff0c;我们如何表示单词的含义&#xff0c;以及Word2Vec方法的基本原…

Ubuntu22 k8s 1.27.1 安装及集群搭建教学(2023.5.16 k8s 最新版本教学,只看这一篇就够了哦!保姆级教程!不行你来找我!)

Ubuntu22 k8s 1.27.1 安装及集群搭建教学&#xff08;2023.5.16 k8s 最新版&#xff0c;只看这一篇就够了哦&#xff01;保姆级教程&#xff01;&#xff01;不行你来找我&#xff01;&#xff09; 温馨提示请仔细阅读&#xff1a;❤️❤️❤️❤️❤️❤️❤️❤️ 1. 由于新版…

Linux系统学习须牢记这几点

工欲善其事须先利其器&#xff0c;想了解Linux技术&#xff0c;先要有一套教学平台,请教同行或者老师来为我们解答&#xff0c;当然也可以下载Cygwin进行学习。但是自主学习的这一过程很困难&#xff0c;因为没有别人的帮助&#xff0c;我们或许会感到迷茫&#xff0c;也会出现…

Spring整合Mybatis、Junit

文章目录 1 Spring整合Mybatis思路分析1.1 环境准备步骤1:准备数据库表步骤2:创建项目导入jar包步骤3:根据表创建模型类步骤4:创建Dao接口步骤5:创建Service接口和实现类步骤6:添加jdbc.properties文件步骤7:添加Mybatis核心配置文件步骤8:编写应用程序步骤9:运行程序 1.2 整合…

STM32F1定时器(TIM1~TIM8)

一、stm32f1定时器简介 1.1、定时器分类 STM32共11个定时器&#xff0c;2个高级控制定时器TIM1和TIM8&#xff0c;4个通用定时器TIM2~TIM5&#xff0c;两个基本定时器TIM6和TIM7&#xff0c;两个看门狗定时器和一个系统滴答定时器Systick. 高级定时器TIM1和TIM8的时钟由APB1产…

想改进婴儿fNIRS数据分析?基于这些先进方法的评估值得一看!

导读 在过去的十年中&#xff0c;fNIRS提供了一种非侵入性的方法来研究发展人群的神经激活。尽管fNIRS在发展认知神经科学中的应用越来越多&#xff0c;但在如何预处理和分析婴儿fNIRS数据方面却缺乏一致性或共识。本研究考察了对婴儿fNIRS数据应用更高级统计分析的可行性&…

智聚北京!相约全球人力资源数智化峰会

人力资源是推动经济社会发展的第一资源。作为我国经济压舱石的中央企业在对标世界一流企业和管理提升方面的持续创新&#xff0c;各行业领军企业围绕组织变革、管理升级、全球化发展走深走实。人力资源管理正从传统职能管理与管控&#xff0c;向紧贴业务战略实现、组织边界和人…