JAVA的IO/NIO?

简介: JAVA的IO/NIO?

最传统的一种IO模式,即在读写的过程中发生阻塞,当用户发起IO请求后,内核会去查看数据是否就绪,如果没有就绪会等待线程就绪,而用户的请求线程就会进入阻塞状态,用户线程交出cpu控制权,当数据准备就绪,内核将会数据拷贝到用户线程,用户线程才会接触block状态。典型的IO模式例子就是data:socket.read()。

 

非阻塞IO则是在read的时候不需要等待,如果得到结果是false,则知道数据没有准备好,这时候则会继续发送read操作,一旦数据在buffe缓存里准备好了,这时候则可以获取到数据,然后返回。所以他的cpu控制权是不是释放的,会一直使用。

 

多路复用IO模式,是目前使用比较多的模式,上面说的非阻塞IO实际上就是多路复用IO,他的工作原理是:有一个线程不断的去轮询多个socket的状态,当socket真的发生了读写事件的时候,才会真正的调用read。这里是一个线程管理多个socket,而不是普通的NIO通过select()方法来read数据,当只有socket真的发生读写的时候,才会占用cpu资源去进行读操作。

另外为何多路复用比NIO效率更高,因为NIO是在不断的发送read查socket数据的,而多路复用,是把有数据的socket放在一个缓存区,轮询看哪个socket有数据,再去read()。不过多路复用IO是通过轮询的方式检测是否有事件大到达,并对事件逐一响应,当某个事件很大的时候,会影响后面事件的处理效率和事件轮播。

 

信号驱动IO,当用户发起一个IO请求的时候,会给对应的socket注册一个信号函数,然后用户线程会继续执行,当内核数据就绪时候会发送信号给用户线程,这时候用户线程会调用IO操作read读数据。

 

异步IO模式可以说是最理想的IO,当用户线程发起读操作的时候就可以去做其他事,完全不会发生阻塞,而内核的角度,java7提供的AsynchronousIO read之后,会立刻返回数据,说明数据已经返回,不会对用户线程block,然后内核数据准备完毕吧数据拷贝到用户线程,然后给用户线程发送一个信号,让他来读取数据,不需要用户线程发起IO操作,意思就是当数据准备完毕,用户线程读取数据之前,IO操作已经结束了。也就是说在异步中,IO的两个操作都不会阻塞,两个阶段都是由内核完成的。

 

JAVA NIO


Java的三大核心部分:Channel(通道),Buffer(缓存区),Selector。传统的IO基于字节和字符进行操作,而NIO则是通过Channel通道和buffer缓存来进行操作,数据总是通过通道发送到缓存,在从缓存读取到通道。Selector选择区用于监听多个通道事件(比如连接打开,数据到达),因此单个线程可以监听多个数据通道。(所以NIO是面向缓冲区的,IO是面向流的)

 

NIO的缓冲区是什么呢?java io面向的是流,意味着每次从流中读取一个或者多个字节,直到全部读取完,不会存在任何地方,此外他不能前后移动流中的数据,如果需要移动,则吧他们先存到缓冲区。NIO的缓冲和java 的io不同,数据先读取到缓冲区,可以在里面前后移动,这就增加了数据处理的灵活性,但是还需要检测缓冲区是否有您处理的数据,已经保证数据量过大的时候,不会覆盖缓冲区里的未处理数据。

 

NIO的非阻塞,io的各种流都是阻塞的,意味着当线程调用read后者write的时候,会进入阻塞状态,不能做任何其他事,直到数据完全查询或者写入。NIO的非阻塞模式使一个线程从通道发送请求数据,但他仅能得到目前缓存区已经有的数据,如果没有数据,则什么都没有获取到,也就不会阻塞影响线程做其他事。非阻塞写也是如此,当线程请求通道写入的时候,不需要等待写入完毕,则可以去做其他事。这就是为什么一个线程可以管理多个输入输出通道channel的原因。

 

Channel和io中的stream流差不多一个等级的。只不过stream是单向的,但是channel是双向的,可以读也可以写。主要实现有FileChannel、DatagramChannel、socketChannel、ServerSocketChannel。

 

Buffer缓冲区实际就是一个容器,一个连续的数组,channel提供从文件网络读取数据的渠道,但是读取和写入都必须经过buffer。    Buffer是一个抽象类,常用的有byteBuffer,intBffer等。他的流程就是数据读的时候先进入buffer然后到通道里,写数据的时候也是先从通道到buffer然后到server。

 

Selector是NIO的一个核心类,selector可以检测多个注册通道是否有事件发生,以便获取事件然后针对每个事件进行响应处理。这样一来只需要单个线程就能处理多个通道,当真的监听到读写时间,才会调用函数,减少了系统的开销,不必为每个连接都创建一个线程,不用维护线程,避免上下文切换。

相关文章
|
4天前
|
存储 监控 Java
Java的NIO体系
通过本文的介绍,希望您能够深入理解Java NIO体系的核心组件、工作原理及其在高性能应用中的实际应用,并能够在实际开发中灵活运用这些知识,构建高效的Java应用程序。
22 5
|
23天前
|
Java
java 中 IO 流
Java中的IO流是用于处理输入输出操作的机制,主要包括字节流和字符流两大类。字节流以8位字节为单位处理数据,如FileInputStream和FileOutputStream;字符流以16位Unicode字符为单位,如FileReader和FileWriter。这些流提供了读写文件、网络传输等基本功能。
42 9
|
1月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
2月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
89 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
2月前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
36 2
|
3月前
|
存储 网络协议 Java
Java NIO 开发
本文介绍了Java NIO(New IO)及其主要组件,包括Channel、Buffer和Selector,并对比了NIO与传统IO的优势。文章详细讲解了FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel及Pipe.SinkChannel和Pipe.SourceChannel等Channel实现类,并提供了示例代码。通过这些示例,读者可以了解如何使用不同类型的通道进行数据读写操作。
Java NIO 开发
|
3月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
2月前
|
Java 数据处理 开发者
揭秘Java IO流:字节流与字符流的神秘面纱!
揭秘Java IO流:字节流与字符流的神秘面纱!
40 1
|
2月前
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
Java IO流全解析:字节流和字符流的区别与联系!
100 1
|
3月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
242 12