Java中处理I/O操作的不同方式

 更新时间:2024年02月07日 09:52:08   作者:IT小辉同学  
BIO、NIO和AIO是Java中处理I/O操作的三种不同方式,它们分别代表阻塞I/O、非阻塞I/O和异步I/O,本文我们结合代码进行一个综合演示,代码由于是伪代码,可能存在不足,仅供大家参考

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

首先,我们需要知道,Java中处理I/O操作的不同方式的不同方式有几种。

BIO、NIO和AIO是Java中处理I/O操作的三种不同方式,它们分别代表阻塞I/O、非阻塞I/O和异步I/O。下面是对它们的详细介绍,在这里我们结合代码进行一个综合演示,代码由于是伪代码,可能存在不足,仅供大家参考:

BIO(Blocking I/O)阻塞I/O:

  • 特点: 在阻塞I/O中,当一个线程在进行I/O操作时,它会被阻塞,直到操作完成。这意味着当一个线程在读取或写入数据时,它无法执行其他任务,直到I/O操作完成。

  • 适用场景: 适用于连接数较少且连接时间较长的情况,例如传统的Socket编程。

  • 代码演示:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BlockingIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            Socket clientSocket = serverSocket.accept(); // 阻塞等待客户端连接
            InputStream inputStream = clientSocket.getInputStream();
            // 处理输入流,阻塞直到数据可读
            int data = inputStream.read();
            System.out.println("Received data: " + data);

            // 其他业务逻辑处理
        }
    }
}

NIO(Non-blocking I/O)非阻塞I/O:

  • 特点: NIO引入了通道(Channel)和缓冲区(Buffer)的概念,以及选择器(Selector)来实现非阻塞I/O。在非阻塞I/O中,一个线程可以管理多个通道,通过选择器监视这些通道的状态,当一个通道可读或可写时,线程可以切换到其他任务,而不需要等待I/O操作完成。

  • 适用场景: 适用于连接数较多但每个连接的交互时间短的情况,例如网络编程中的聊天室。

  • 代码演示:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NonBlockingIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8888));
        serverSocketChannel.configureBlocking(false);

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            selector.select();
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

            while (keyIterator.hasNext()) {
                SelectionKey key = keyIterator.next();

                if (key.isAcceptable()) {
                    // 处理连接
                    SocketChannel clientChannel = serverSocketChannel.accept();
                    clientChannel.configureBlocking(false);
                    clientChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    // 处理读事件
                    SocketChannel clientChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = clientChannel.read(buffer);
                    System.out.println("Received data: " + new String(buffer.array(), 0, bytesRead));

                    // 其他业务逻辑处理

                    clientChannel.close();
                }

                keyIterator.remove();
            }
        }
    }
}

AIO(Asynchronous I/O)异步I/O:

  • 特点: AIO引入了异步I/O操作,其中读/写请求被提交给操作系统,而应用程序继续执行其他任务。当操作系统完成I/O操作时,会通知应用程序,这样就实现了异步的I/O操作。

  • 适用场景: 适用于连接数较多且每个连接的交互时间不确定的情况,例如在高并发的网络服务器中。

  • 代码演示:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AsyncIOServer {
    public static void main(String[] args) throws IOException {
        AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8888));

        serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
            @Override
            public void completed(AsynchronousSocketChannel clientChannel, Void attachment) {
                serverSocketChannel.accept(null, this);
                // 继续接收下一个连接
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                    @Override
                    public void completed(Integer bytesRead, ByteBuffer buffer) {
                        System.out.println("Received data: " + new String(buffer.array(), 0, bytesRead));
                        // 其他业务逻辑处理
                        clientChannel.close();
                    }

                    @Override
                    public void failed(Throwable exc, ByteBuffer buffer) {
                        // 处理读取失败
                    }
                });
            }

            @Override
            public void failed(Throwable exc, Void attachment) {
                // 处理接受连接失败
            }
        });

        // 阻塞主线程,保持服务端运行
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总的来说,BIO适用于连接数较少且连接时间较长的场景,NIO适用于连接数较多但每个连接的交互时间短的场景,而AIO适用于连接数较多且每个连接的交互时间不确定的场景。选择合适的I/O模型取决于具体的应用需求。在Java中,NIO和AIO是在Java 1.4 和 Java 7 中引入的,分别位于java.niojava.nio.channels包中。

以上就是Java中处理I/O操作的不同方式的详细内容,更多关于Java处理I/O操作的资料请关注脚本之家其它相关文章!

相关文章

  • SpringMVC之RequestContextHolder详细解析

    SpringMVC之RequestContextHolder详细解析

    这篇文章主要介绍了SpringMVC之RequestContextHolder详细解析,正常来说在service层是没有request的,然而直接从controlller传过来的话解决方法太粗暴,后来发现了SpringMVC提供的RequestContextHolder,需要的朋友可以参考下
    2023-11-11
  • Springboot轻量级的监控组件SpringbootAdmin

    Springboot轻量级的监控组件SpringbootAdmin

    这篇文章主要为大家介绍了Springboot轻量级的监控组件SpringbootAdmin使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Java实现JWT登录认证的示例代码

    Java实现JWT登录认证的示例代码

    Java中我们可以使用诸如JJWT这样的库来生成和验证JWT,本文主要介绍了Java实现JWT登录认证的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • java &与&&的区别及实例

    java &与&&的区别及实例

    这篇文章主要介绍了java &与&&的区别的相关资料,并附简单实例,帮助大家学习理解这部分知识,需要的朋友可以参考下
    2016-10-10
  • 简单操作实现Java jsp servlet文件上传过程解析

    简单操作实现Java jsp servlet文件上传过程解析

    这篇文章主要介绍了简单操作实现Java jsp servlet文件上传过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • token工作机制及原理附Java生成token工具类

    token工作机制及原理附Java生成token工具类

    这篇文章介绍了token工作机制及原理,内附Java生成token工具类Demo。对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-12-12
  • struts2 中文乱码的解决办法分享

    struts2 中文乱码的解决办法分享

    这篇文章主要介绍了struts2 中文乱码的解决办法,需要的朋友可以参考下
    2014-02-02
  • 详解Mybatis中javaType和ofType的区别

    详解Mybatis中javaType和ofType的区别

    本文主要介绍了详解Mybatis中javaType和ofType的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • SpringBoot之拦截器与过滤器解读

    SpringBoot之拦截器与过滤器解读

    这篇文章主要介绍了SpringBoot之拦截器与过滤器解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java排序算法中的快速排序算法实现

    Java排序算法中的快速排序算法实现

    这篇文章主要介绍了Java排序算法中的快速排序算法实现,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,需要的朋友可以参考下
    2023-12-12

最新评论