IO和NIO的主要区别在哪里?

Java 中的 IO(输入/输出)和 NIO(新输入/输出)都是处理输入和输出操作的方式,它们的主要区别在于如何处理数据的读写。

  1. 阻塞与非阻塞:

    • IO是阻塞的,这意味着当一个线程调用read()或write()时,该线程被阻塞,直到有一些数据被读取或写入。该线程在此期间不能再做任何事情了。
    • NIO则可以非阻塞地进行读写操作。当线程从通道读取数据到缓冲区或从缓冲区写入通道时,线程可以同时进行其他任务。线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作,所以一个线程现在可以管理多个输入和输出通道(channel)。
  2. 选择器/多路复用器:

    • NIO有选择器的概念,选择器能够监控多个开放的通道,检查哪个通道准备好了进行读写。 这种模式使得一个单独的线程可以管理多个通道。
  3. 数据处理:

    • IO面向流(Stream Oriented),即一个流必须从一个地方移动到另一个地方。它能够持续、顺序地处理数据。但不能随机访问数据,每次只能从头开始。
    • NIO面向缓冲(Buffer Oriented),这意味着数据是直接读到或写自一个缓冲区的。可以随时回到缓冲区,重新读取数据,但这在IO操作中是不可能的。

这就是IO和NIO的主要区别。

重点讲一下选择器怎么运行的:

NIO通过使用Selector选择器来监控通道。选择器是Java NIO提供的一个对象,它可以注册到多个通道上,监听通道中发生的事件(操作如何就绪)。接下来的段落会解释NIO是如何使用选择器来监控通道的。

首先,你需要创建一个Selector对象:

java 复制代码
Selector selector = Selector.open();

然后,你可以将一个或多个通道(通常是ServerSocketChannel或SocketChannel)注册到这个Selector:

java 复制代码
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);

上面的代码首先将通道设置非阻塞模式,然后将通道注册到选择器上,关注(或说"订阅")读就绪事件。OP_READ是一个常量,表示读操作就绪的事件。

现在,已经设置好了通道和选择器,接下来就可以使用选择器来轮询哪个注册的通道准备好了某个操作。下面就是一个基本的选择循环:

java 复制代码
while (true) {
    int readyChannels = selector.select();
    if(readyChannels == 0) continue;
    Set<SelectionKey> selectedKeys = selector.selectedKeys();
    Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
    while(keyIterator.hasNext()) {
        SelectionKey key = keyIterator.next();
        if(key.isReadable()) {
            // a channel is ready for reading
        } else if (key.isWritable()) {
            // a channel is ready for writing
        }
        keyIterator.remove();
    }
}

在上述代码中,selector.select()阻塞等待直至至少有一个注册的通道就绪。接着,使用selectedKeys()方法来访问就绪的通道,这个方法返回一个SelectionKey对象的集合,每一个SelectionKey对象都代表了一个注册到这个选择器的、已经就绪的通道。

通过isReadable()isWritable()方法,你可以检查通道的读或写事件是否已经就绪。如果这些方法返回true,那么你就可以开始进行读或写操作了。

以上就是Java NIO如何使用选择器来监控多个通道的基本过程。请注意这只是一个基础例子,真实的使用中还需要处理更多问题,例如处理异常,配置通道和选择器等。

相关推荐
程序员-周李斌2 小时前
Java NIO [非阻塞 + 多路复用解]
java·开发语言·开源软件·nio
onAcorner5 天前
Netty/Redis网络模型——IO多路复用原理(操作系统)
netty·nio
C2H5OH66610 天前
Netty详解-02
java·websocket·网络协议·tcp/ip·tomcat·netty·nio
Moshow郑锴13 天前
Spring Boot 多线程文件复制服务(支持大文件流式/NIO复制、失败重试、覆盖写入)
nio
java干货16 天前
BIO是“一人盯一桌”,NIO是“一人管全场”,AIO是“机器人送餐”
java·机器人·nio
Luo_xguan16 天前
一、Netty-高并发IO底层原理(5种主要的IO模型)
java·服务器·netty·nio
007php00716 天前
某游戏大厂的常用面试问题解析:Netty 与 NIO
java·数据库·游戏·面试·职场和发展·性能优化·nio
爱吃烤鸡翅的酸菜鱼23 天前
如何掌握【Java】 IO/NIO设计模式?工厂/适配器/装饰器/观察者模式全解析
java·开发语言·后端·设计模式·nio
Full Stack Developme1 个月前
java.nio 包详解
java·python·nio
编啊编程啊程1 个月前
【004】生菜阅读平台
java·spring boot·spring cloud·dubbo·nio