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

相关推荐
自律的kkk7 天前
网络编程中的黏包和半包问题
java·开发语言·网络·网络编程·tcp·nio
power-辰南8 天前
Netty 常见面试题原理解析
java·开发语言·netty·nio
生活百般滋味,人生需要笑对。 --佚名11 天前
NIO 三大组件
java·开发语言·nio
鹏码纵横16 天前
如何解决 java.nio.charset.CoderMalfunctionError: 编码器故障错误问题?亲测有效的解决方法!
java·python·nio
智商低情商凑16 天前
NIO - selector简单介绍
java·开发语言·nio
智商低情商凑19 天前
Netty - NIO基础学习
nio
小猫猫猫◍˃ᵕ˂◍20 天前
NIO和零拷贝
linux·服务器·nio
程序猿进阶20 天前
ChannelInboundHandlerAdapter 与 SimpleChannelInboundHandler 的区别
java·开发语言·后端·面试·性能优化·netty·nio
材料苦逼不会梦到计算机白富美21 天前
多人聊天室 NIO模型实现
运维·服务器·nio
jupiter_88821 天前
Java NIO channel
java·服务器·nio