BIO/NIO示例分析

01-IO模型(BIO、NIO、AIO) 目录一、IO模型分类1.1 阻塞型 IO1.2 非阻塞型 IO1.3 I/O 多路复用1.4 信号驱动 I/O1.5 异步 I/O1.6 五大 I/O 模型比较二、BIO、NIO与AIO2.1 BIO2.1.1 传统 BIO2.1.2 伪异步 IO1.3 代码示例2.2 NIO (New I/O)2.2.1 NIO 简介2.2.2 NIO与BIO的区别(1)Non-blocking(非阻塞)(2)Buffer(缓冲区)(3)Channel (通道)(4)Selector (选择器)2.2.3 代码示例2.3 阅读详情

BIO

BIO,同步阻塞IO,实现模式是一个连接一个线程。
例如:网络编程socket,每次客户端发起一个连接请求就启动一个线程处理数据传递操作,如果第一个连接未做任何操作,则一直占用线程导致其他客户端数据无法传递到服务端。

示例代码演示说明,启动服务:

public class SocketServer {

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(SocketConstant.SOCKET_SERVER_PORT)) {
            while (true) {
                System.out.println(">>>>>>建立socket,监听客户端。");
                Socket socket = serverSocket.accept();
                InputStream inputStream = socket.getInputStream();
                System.out.println(">>>>>>接收socket输入流。");
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String message = null;
                if ((message = bufferedReader.readLine()) != null) {
                    System.out.println(">>>>>>服务端打印消息:[" + message + "]");
                }
                socket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

服务端控制台输出:

>>>>>>建立socket,监听客户端。

此时socket服务已启动,并处理阻塞状态,监听来自指定端口的客户端请求。
然后,执行客户端请求并输入传递数据。

public class SocketClient {

    public static void main(String[] args) {
        try (Socket socket = new Socket(SocketConstant.SOCKET_SERVER_IP, SocketConstant.SOCKET_SERVER_PORT);
             OutputStream outputStream = socket.getOutputStream();) {

            Scanner scanner = new Scanner(System.in);
            System.out.println("客户端输入消息:");
            String message = scanner.nextLine();
            outputStream.write(message.getBytes(SocketConstant.SOCKET_CODE_MA));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

客户端控制台输入:

客户端输入消息:
socket演示BIO同步阻塞IO示例

客户端输入数据后回车发送至服务端。
服务端控制台输出效果:

>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[socket演示BIO同步阻塞IO示例]
>>>>>>建立socket,监听客户端。

最后,服务端正常接收到客户端传递数据后,又重新阻塞,建立监听等待下一次客户端请求。

这次我们连续执行两次客户端请求,第一次请求后不输入传递数据,第二次请求后输入传递数据,结果服务端执行了接收socket客户端输入流操作,但是没有接收到任何数据。
服务端控制台输出效果:

>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[socket演示BIO同步阻塞IO示例]
>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。

为什么第二次客户端请求输入的数据没有在服务端输出呢?
因为客户端第一次请求后,服务端监听到了但是由于客户端没有传递数据所以线程阻塞在数据接收这里,而第二次客户端请求虽然输入了数据但是因为第一次还未执行完成,线程被占用处于阻塞中,所以只能等待第一次执行完成。
那么我们在第一次客户端请求中输入数据执行,就可以看到服务端不仅接收到了第一次的数据传递也接收到了第二次的数据传递。
服务端控制台输出效果:

>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[socket演示BIO同步阻塞IO示例]
>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[第一次客户端数据内容。]
>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[第二次客户端请求。]
>>>>>>建立socket,监听客户端。

上述示例,阻塞出现在了服务监听和数据接收。我们可以使用多线程优化,保证客户端的提交不会因为线程被占用而阻塞,修改服务端代码如下:

public class SocketThreadServer {

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(SocketConstant.SOCKET_SERVER_PORT)) {
            while (true) {
                System.out.println(">>>>>>建立socket,监听客户端。");
                Socket socket = serverSocket.accept();
                new Thread(new SocketThreadRun(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //开启线程接收客户端消息
    static class SocketThreadRun implements Runnable{

        Socket socket;

        public SocketThreadRun(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            InputStream inputStream = null;
            try {
                inputStream = socket.getInputStream();
                System.out.println(">>>>>>接收socket输入流。");
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String message = null;
                if ((message = bufferedReader.readLine()) != null) {
                    System.out.println(">>>>>>服务端打印消息:[" + message + "]");
                }
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

启动新的多线程服务端,再启动多个客户端输入数据进行传递,就不会互相影响了。
服务端控制台输出效果:

>>>>>>建立socket,监听客户端。
>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>建立socket,监听客户端。
>>>>>>接收socket输入流。
>>>>>>服务端打印消息:[第二个客户端请求的内容。]

注意,如果并发量过高,需要开启大量线程消耗过多内存,并且系统过度频繁的调用也会降低性能。为了降低频繁的创建和销毁对象,因此提出了线程池的概念,提前创建好一个线程池,包含若干空闲线程,需要时直接调用。

public class SocketThreadPoolServer {

    public static void main(String[] args) {
    	//首先创建线程池,指定线程数量为SocketConstant.SOCKET_THREAD_POOLS。
        ExecutorService executorService = Executors.newFixedThreadPool(SocketConstant.SOCKET_THREAD_POOLS);
		
        try (ServerSocket serverSocket = new ServerSocket(SocketConstant.SOCKET_SERVER_PORT)) {
            while (true) {
                System.out.println(">>>>>>建立socket,监听客户端。");
                Socket socket = serverSocket.accept();
                executorService.execute(new SocketThreadRun(socket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        executorService.shutdown();

    }

    //开启线程接收客户端消息
    static class SocketThreadRun implements Runnable{

        Socket socket;

        public SocketThreadRun(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            InputStream inputStream = null;
            try {
                inputStream = socket.getInputStream();
                System.out.println(">>>>>>接收socket输入流。");
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                String message = null;
                if ((message = bufferedReader.readLine()) != null) {
                    System.out.println(">>>>>>服务端打印消息:[" + message + "]");
                }
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

我们虽然做了一层层优化,但是并没有消除阻塞,因为即使是线程池也是有边界的,比如线程池中初始化100个空闲线程,但是并发量超过100,而且正在执行的100个线程如果一直未执行数据传递,导致线程池被占满,那么其他请求还是只能等待阻塞处理。这种情况还浪费了很多系统资源,因为只是启动了100个阻塞线程并不一定会占用多少内存和CPU计算资源,那么我们是否可以让发生阻塞的线程重新空闲出来给排队的其他请求使用呢?>。< 想得美!

NIO

NIO,New IO, 同步非阻塞IO,实现模式是一个请求一个线程。java1.4版本开始推出的。
例如:Socket发起一个连接请求,先注册在选择器上,只有检测到该连接发生了I/O请求后才会启动或占用一个线程。

NIO示意图
NIO核心思想是事件驱动,它包含三个重要的组件Selector选择器,Channel通道和Buffer缓存区。如上图所示NIO的执行流程示意图,第一步开启一个选择器线程循环执行,它会监听通道的事件是否就绪(如数据是否输入);第二步将Channel都注册在选择器上;第三步一旦Channel上的事件就绪了(如数据已经输入)就会交给线程去执行,这里可以是单线程也可以是线程池,NIO完全可以实现单线程执行多请求,如果使用线程池也只需要开启CPU核心数量就足够了,因为这里执行是不会发生阻塞的,不需要消耗多余资源与性能。
Buffer缓存区则可以理解为是数据的中转站,数据的读写都是通过Buffer完成;Channel则是数据的通道,指向数据的源头或者目的地,执行对Buffer对象的读写操作。
NIO服务端代码:

public class NIOServer {

    public static void main(String[] args) {

        try {
            //1.创建Selector
            Selector selector = Selector.open();
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

            serverSocketChannel.bind(new InetSocketAddress(SocketConstant.SOCKET_SERVER_PORT));

            //2.注册到selector
            serverSocketChannel.configureBlocking(false);//设置为非阻塞状态
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);//注册监听'连接'状态
            ExecutorService executorService = Executors.newFixedThreadPool(SocketConstant.CPU_THREAD_POOLS);//开启线程池

            //3.监听事件
            int taskcount = 0;//计数器

            while (true) {
                //阻塞等待事件就绪,但是阻塞可能会释放返回0,增加判断保持阻塞。
                int op_channel_count = selector.select();
                if (op_channel_count == 0) {
                    continue;
                }
                //获得selector监听到就绪事件集合
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
                while (selectionKeyIterator.hasNext()) {
                    SelectionKey selectionKey = selectionKeyIterator.next();
                    if (selectionKey.isAcceptable()) {//监听到连接状态(OP_ACCEPT),仅ServerSocketChannel支持
                        serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
                        SocketChannel channel = serverSocketChannel.accept();
                        channel.configureBlocking(false);
                        channel.register(selector, SelectionKey.OP_READ, ++taskcount);
                    } else if (selectionKey.isReadable()) {//监听到读取状态(OP_READ)
                        executorService.execute(new SocketThreadPool(selectionKey));//将事件交给线程池处理具体业务
                        selectionKey.cancel();//*取消掉selector注册,避免线程池处理不及时重复选择。
                    } else if (selectionKey.isConnectable()) {//监听到连接状态(OP_CONNECT),客户端可支持。

                    } else if (selectionKey.isWritable()) {//监听到写入状态(OP_WRITE)

                    }
                    //任务处理完成后从集合中移除
                    selectionKeyIterator.remove();
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    //开启线程处理任务
    static class SocketThreadPool implements Runnable {

        SelectionKey selectionKey;

        public SocketThreadPool(SelectionKey selectionKey) {
            this.selectionKey = selectionKey;
        }

        @Override
        public void run() {
            try {
                System.out.println("[" + selectionKey.attachment() + "]连接数据:" + getChannelData());
                selectionKey.channel().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //Plus01.解析channel读取Buffer的数据
        private String getChannelData() throws IOException {
            SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
            //Buffer必须指定一个大小
            ByteBuffer byteBuffer = ByteBuffer.allocate(SocketConstant.NIO_BUFFER_SIZE);
            //为了接收全部的内容后再转换,需要定义一个更大的Buffer
            ByteBuffer resultByteBuffer = null;
            int bufferCount = 0;

            //读取socketChannel,返回-1表示读取完毕。
            while ((socketChannel.read(byteBuffer) != -1)) {
                bufferCount++;
                ByteBuffer tempByteBuffer = ByteBuffer.allocateDirect(SocketConstant.NIO_BUFFER_SIZE * (bufferCount + 1));
                if (resultByteBuffer != null) {
                    resultByteBuffer.flip();//设置为读模式
                    tempByteBuffer.put(resultByteBuffer);
                }
                resultByteBuffer = tempByteBuffer;
                byteBuffer.flip();
                resultByteBuffer.put(byteBuffer);
                byteBuffer.clear();
            }

            if (resultByteBuffer != null) {
                resultByteBuffer.flip();
                Charset charset = Charset.forName(SocketConstant.SOCKET_CODE_MA);
                CharsetDecoder charsetDecoder = charset.newDecoder();
                return charsetDecoder.decode(resultByteBuffer).toString();
            }
            return "";
        }
    }

}

NIO客户端:

public class NIOClient {
    public static void main(String[] args) {
        try(SocketChannel socketChannel = SocketChannel.open()){
            socketChannel.connect(new InetSocketAddress(SocketConstant.SOCKET_SERVER_IP,SocketConstant.SOCKET_SERVER_PORT));
            Scanner scanner = new Scanner(System.in);
            System.out.println("NIO客户端输入消息:");
            String message = scanner.nextLine();
            ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes(SocketConstant.SOCKET_CODE_MA));
            while (byteBuffer.hasRemaining()){
                socketChannel.write(byteBuffer);
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

通过代码示例,可以直观感受到,当客户端连接时服务端会执行哪个监听动作,当客户端发送数据时服务端又会执行哪个监听动作,这就是事件驱动的好处,不会因为未完成某个事件而阻塞整个线程,更高的利用了系统资源。

R语言笔记十:独立性检验函数 1.独立性检验函数        独立性检验是根据频数信息判断两类因子彼此相关或相互独立的假设检验。所谓独立性就是指变量之间是独立的,没有关系。 独立性检验算法:卡方检验、Fisher检验、Cochran-Mantel-Haenszel检验 2.假设检验 假设检验(Hypothesis Testing)是数理统计学中根据一定假设条件由样本推断总体的一种方法。 原假设——没有发生 备择假设——发生了 具体做法:根据问题的需要对所研究的总体作 阅读详情

相关推荐

使用【阿里云百炼】搭建自己的大模型

本文介绍阿里云百炼大模型平台,其为企业级服务平台,融合通义千问等模型,支持多模态能力,提供一站式工具降低开发门槛。重点讲解智能体应用及大模型搭建步骤,含进入创新应用界面、选模型配参数、输指令、导数据、加载知识库、获取API Key、加样例库、配置MCP,还提及模型调试与多平台发布,并附试用链接,助力企业与开发者快速搭建适配业务的AI模型。

Larry的博客 4738

openssl之BIO系列之6---BIO的IO操作函数

这些函数是BIO的基本读写操作函数,包括四个,他们的定义如下(openssl/bio.h):      int BIO_read(BIO *b, void *buf, int len);      int BIO_gets(BIO *b,char *buf, int size);      int BIO_write(BIO *b, const void *buf, int len);  

fryingpan的专栏 1067

C#与西门子PLC通讯——新手快速入门

本文基于C# .Net Core和西门子博图TIA Portal V17搭建。由于手边没有西门子PLC实物,所以采用S7-PLCSIM Advanced V4.0作为模拟PLC,以实现0成本完成通讯测试实例。这篇入门笔记解决了新手第一次上手实践时遇到的坑,并且有意忽略了实际项目中会遇到的逻辑交互和更多的数据格式问题。

吾家有猫名探花的博客 2万+

BIO 实例代码

BIO 典型的一请求,一应答通信模型缺点:该模型最大的问题就是,当客户端数量增加时,服务端的线程数与客户端并发的数量是 1:1 关系,我们知道在jvm 中线程是非常宝贵的资源,当线程数不断上升时,系统性能将不断下降,可能会出现堆栈溢出,创建线程失败等问题,并最终导致宕机或者僵死,不对外提供服务,下面就进行演示BIO编程模型。1.TimeServer public class TimeServer

qq_27061805的博客 1162

AOI检测总误判?五大常见问题与实战解决方案

通过对图像质量、检测程序、外界干扰、算法优化以及设备维护和校准的全面把控,企业可以有效降低误判率,提升AOI检测的准确性和可靠性,为工业生产提供更有力的质量保障。表现描述:在AOI检测时,元器件字符因印刷颜色深浅、模糊或受到灰尘干扰等差异,再加上元件库参数未根据实际生产优化,会使系统误将合格元件判定为不合格,严重影响生产效益和产品质量。优化元件库:着重检测关键差异字符,如型号编码等关键信息,剔除不必要字符的检测项,减少干扰,专注于关键识别的准确性。检测时,根据物料信息动态更新检测参数,使系统适应物料变化。

ALeader_AOI的博客 3493

8.时间序列预测

目标:使用历史数据预测未来的销售额。通过以上步骤,可以在Excel中有效进行预测分析,帮助做出更准确的决策通过考虑不同时期数据的影响,可以显著提高预测的准确性。结合多种方法和模型,可以灵活应对复杂的市场环境和变化。

学习,输出==》再学习再输出 891

openssl之BIO系列之15---内存(mem)类型BIO

内存(mem)类型BIO所定义的相关系列函数如下(openssl/bio.h):      BIO_METHOD * BIO_s_mem(void);           BIO_set_mem_eof_return(BIO *b,int v)      long BIO_get_mem_data(BIO *b, char **pp)      BIO_set_mem_buf(BIO *

fryingpan的专栏 3850

手眼标定----眼在手上(eye-in-hand)

@TOC 标定之前你可以先拿个怡宝盖子进行测试。 第一步:打开halcon,采集,然后生成代码,显示十字架 第二步:把怡宝盖子放在十字架中心位置,在图像处理,找到怡宝盖子 第三步:找到怡宝盖子然后进行九点标定(眼在外帖子有讲),移动机器手然后分别拍9次照片,记录怡宝盖子坐标和当前机器坐标。这里移动到中心位置的时候记录一下单独记录一下坐标,等下要用。 顺序 第四步:拍完后利用vector_to_hom_mat2d算子求出矩阵,然后在利用write_tuple (HomMat2D, ‘路径’)进行保存。这里

苏州程序大白的博客 4280

Openssl之BIO系列(3)

17.连接(connect)类型BIO 该类型的BIO封装了socket的Connect方法,它使得编程的时候可以使用统一的BIO规则进行socket的connect连接的操作和数据的发送接受,而不用关心具体平台的Socket的connect方法的区别。其相关定义的一些函数如下(openssl\bio.h): BIO_METHOD * BIO_s_connect(void); #defi

Live_Today的专栏 2786

18、基于FSDD数据集的深度学习案例分析

本文基于FSDD(Free Spoken Digit Dataset)数据集,系统介绍了深度学习在语音数字识别中的应用。内容涵盖动态与静态计算图的对比、数据预处理流程(包括数据增强、固定长度处理和归一化)、监督学习与无监督学习的模型构建与训练过程,并通过实验对比了不同网络架构的性能。文中使用PyTorch实现2层全连接网络和自编码器模型,展示了正则化技术对提升模型准确率的关键作用。最后总结了关键技术并提出了实际应用建议,展望了未来在复杂模型、多模态融合和实时应用方向的发展潜力。

vscode6remote的博客 259

【同等学力】01-逻辑符号表达

F(x): x是确诊者,G(x):x有症状F(x): x是老人,G(x):x是宠物,L(x,y): x喜欢y。

super_mochi1 1879

BIO与NIO简单示例

BIO模型 同步并阻塞(传统阻塞型),服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销。 示意图: 在BIO模型中,每一个客户端与服务器的链接都会创建一个线程,无论客户端是否向服务器发送数据。 代码验证 public class BIOServer { public static void main(String[] args) throws IOException { //创建一个线程池

qq_43750656的博客 355

Arcgis建筑面shp由DSM和DEM获取高度拉伸并可视化

Arcgis建筑面shp由DSM和DEM获取高度拉伸并可视化

yilvyangguang520的博客 3990

I/O 模型学习笔记【全面理解BIO/NIO/AIO】

I/O 模型概念,全面理解BIO/NIO/AIO ,面试相关。NIO概念,聊天室代码示例,零拷贝等概念。

qq_33129875的博客 1113

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IO-BIO NIO

IO-BIO NIO

qq_41017363的博客 135

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java NIO(一):认识NIO

本文介绍了Java NIO的核心概念与应用场景。NIO通过缓冲区、通道和选择器三大组件,解决了传统IO在高并发和大数据量传输时的性能瓶颈。文章对比了BIO与NIO的差异,详细解析了Buffer的工作原理和Channel类型,并举例说明了Selector在多路复用中的优势。通过文件拷贝的代码示例展示了NIO的实际应用,同时从直接内存和零拷贝两方面解释了NIO的性能优势。最后指出BIO适用于简单场景,而NIO更适合高并发网络应用,并建议网络编程优先使用Netty框架而非原生NIO。全文系统性地阐述了NIO的核心

欧阳方超的专栏 1147

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

BIO演变NIO的过程

随手点赞,养成习惯

qq_16841391的博客 319

c++ socket编程_网络编程NIO:BIO和NIO

作者 | 小高飞来源 | urlify.cn/BBbuInBIOBIO(Blocking I/O),同步阻塞,实现模式为一个连接一个线程,即当有客户端连接时,服务器端需为其单独分配一个线程,如果该连接不做任何操作就会造成不必要的线程开销。BIO是传统的Java io编程,其相关的类和接口在java.io 包下。BIO适用于连接数目较小且固定的架构,对服务器资源的要求较高,是JDK1.4以前的唯...

weixin_39789979的博客 976

bio、nio、aio的区别以及使用场景

本文分析了Java中三种IO模型(BIO/NIO/AIO)的核心差异。BIO采用同步阻塞方式,每个连接需要单独线程处理,编程简单但并发能力差;NIO通过Selector多路复用实现同步非阻塞,单线程可处理多连接,适合高并发场景;AIO基于异步非阻塞模型,由操作系统完成IO操作后回调通知,性能最高但编程复杂。文章从原理、代码示例、优缺点等方面进行对比,指出BIO适合简单场景,NIO广泛应用于高并发网络服务(如Netty),而AIO依赖操作系统支持,适合耗时IO操作。三种模型在阻塞/非阻塞、同步/异步两个维度上

qq_52531977的博客 1091

NIO和BIO异同及实践

NIO和BIO对比 NIO(non blocking I/O)非阻塞I/O,jdk1.4引入的新I/O,平时接触的文件的I/O操作是BIO,即阻塞I/O BIO API使用 具体流程: A.测试accept()方法的阻塞 public void testAccept() throws IOException{ ServerSocket ss = new ServerSocket(); ss.bind(new InetSocketAddress(9999)); Socket sk = s

QuietThinking的博客 279

Java 性能优化之——从BIO 到 NIO,再到 AIO

Netty 的高性能架构,是基于一个网络编程设计模式 Reactor 进行设计的。现在,大多数与 I/O 相关的组件,都会使用 Reactor 模型,比如 Tomcat、Redis、Nginx 等,可见 Reactor 应用的广泛性。 Reactor 是 NIO 的基础。为什么 NIO 的性能就能够比传统的阻塞 I/O 性能高呢?首先来看一下传统阻塞式 I/O 的一些特点 阻塞 I/O 模型 如上图,是典型的BIO 模型,每当有一个连接到来,经过协调器的处理,就开启一个对应的线程进行接管。如.

vincent_wen0766的博客 783

聊聊分布式架构05——[NIO基础]BIO到NIO的演进

聊聊分布式架构中的IO模型——BIO到NIO的演进

Elaine2391的博客 695

Java基础教程(十一)输入和输出:Java I/O 终极指南,从 BIO 到 NIO.2 的深度剖析与实战技巧

本文深度解析 Java I/O 核心机制。传统 BIO 以流(InputStream/OutputStream, Reader/Writer)处理字节/字符,但同步阻塞制约性能。NIO 引入通道(Channel)、缓冲区(Buffer)和选择器(Selector),实现非阻塞与多路复用,显著提升吞吐量。NIO.2(Java 7+)通过 Path、Files 简化文件操作,并提供了异步通道(AsynchronousFileChannel)支持。关键点在于:BIO 简单但性能受限;NIO 高性能但编码复杂;NI

jxf_jxfcsdn的博客 513

BIO,NIO,AIO 简要总结

文章目录BIO,NIO,AIO 总结1. BIO (Blocking I/O)1.1 传统 BIO1.2 伪异步 IO1.3 代码示例1.4 总结2. NIO (New I/O)2.1 NIO 简介2.2 NIO的特性/NIO与IO区别1)Non-blocking IO(非阻塞IO)2)Buffer(缓冲区)3)Channel (通道)4)Selectors(选择器)2.3 NIO 读数据和写数据...

VicterTian的博客 1731

Java BIO NIO对文件的操作

CharBuffer:抽象类 通过CharBuffer.allocate()获取 HeapCharBuffer 类型 toString方法实现:new String(char[],开始位置,截取长度); BtyeBuffer:抽象类,同上,通过Charset.newDecode()(返回CharsetDecode类).Decode(btyebuffer,charbuffer,true);进行转换, NIO对文件的操作如下: import java.io.*; import java.nio...

qq_37752258的博客 213

Java中处理I/O操作的不同方式:BIO,NIO,AIO

总的来说,BIO适用于连接数较少且连接时间较长的场景,NIO适用于连接数较多但每个连接的交互时间短的场景,而AIO适用于连接数较多且每个连接的交互时间不确定的场景。在非阻塞I/O中,一个线程可以管理多个通道,通过选择器监视这些通道的状态,当一个通道可读或可写时,线程可以切换到其他任务,而不需要等待I/O操作完成。BIO、NIO和AIO是Java中处理I/O操作的三种不同方式,它们分别代表阻塞I/O、非阻塞I/O和异步I/O。在阻塞I/O中,当一个线程在进行I/O操作时,它会被阻塞,直到操作完成。

IT小辉同学 1428
上一篇: OCR——光学字符识别
下一篇: Java基础——线程安全
Droy`Z
博客等级 码龄19年 75粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值