当前位置: 首页 > news >正文

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

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

http://www.lryc.cn/news/331604.html

相关文章:

  • 爬虫部署平台crawlab使用说明
  • uniapp uni.scss中使用@mixin混入,在文件引入@include 样式不生效 Error: Undefined mixin.(踩坑记录一)
  • Redis的5大常见数据类型的用法
  • 刘小光本就疑心赵本山与他媳妇李琳有染,赵本山为证实清白便想起蛋糕上的字,结果呢?
  • Unity之PUN实现多人联机射击游戏的优化(Section 2)
  • 多叉树题目:N 叉树的层序遍历
  • 时序数据库IoTDB:功能详解与行业应用
  • 信息系统项目管理师——第18章项目绩效域管理(一)
  • WebSocket用户验证
  • NOSQL(非关系型数据库)的优缺点有哪些?
  • 个人推荐Redis比较好的一种使用规范
  • 【教程】宝塔default.db占用空间几十g解决方法|宝塔占用磁盘空间特别大解决方法|宝塔磁盘被占满怎么清理
  • Unity类银河恶魔城学习记录11-15 p117 Ice and Fire item Effect源代码
  • Qt QML的枚举浅用
  • 设计模式:单例模式六种实现
  • Mybatis-Plus05(分页插件)
  • python爬取B站视频
  • 深度学习500问——Chapter05: 卷积神经网络(CNN)(2)
  • 基于单片机的测时仪系统设计
  • 鸿蒙原生应用开发-网络管理Socket连接(三)
  • 【Java EE】关于Maven
  • 每日一题:C语言经典例题之反转数
  • RESTfull接口访问Elasticsearch
  • NoSQL之Redis
  • double二分(P3743 小鸟的设备)
  • 【独立开发前线】Vol.36 为什么从2023年开始,独立开发者越来越多了?
  • GPT4不限制使用次数了!GPT5即将推出了!
  • 物联网实战--入门篇之(六)嵌入式-WIFI驱动(ESP8266)
  • Java并发编程基础面试题详细总结
  • EKO / 砍树