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

admin2024-04-03  1

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对象:

Selector selector = Selector.open();

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

channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);

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

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

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如何使用选择器来监控多个通道的基本过程。请注意这只是一个基础例子,真实的使用中还需要处理更多问题,例如处理异常,配置通道和选择器等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!