IO跟NIO的区别
IO跟NIO的区别
1. 面向流跟面向缓存
1.1 面向流意味着每次只能从流中一个或多个字节的读取,直至读完,没有被缓存到任何地方
1.2 Java NIO提供了channel,Channel和传统的io中的stream很相似,但也有很大区别,主要区别 就是通道是双向的,通过channel能读也能写,它将数据读取到一个稍后处理的缓冲区,需要的时候可在缓冲区前后移动,这就增加了处理过程中的灵活性。但是还需要检查该缓冲区是否有所需要的数据,而且确保新添加的数据不会覆盖缓冲区尚未处理的数据。
2. 阻塞与非阻塞
2.1 io的各种流是阻塞的,就是当一个线程调用读写方法时,该线程会被阻塞,直到读写完,在这期间该线程不能干其他事,CPU转而去处理其他线程,假如一个线程监听一个端口,一天只会有几次请求进来,但是CPU却不得不为该线程不断的做上下文切换,并且大部分切换以阻塞告终。
2.2 NIO通讯是将整个任务切换成许多小任务,由一个线程负责处理所有io事件,并负责分发。它是利用事件驱动机制,而不是监听机制,事件到的时候再触发。NIO线程之间通过wait,notify等方式通讯。保证了每次上下文切换都有意义,减少无谓的进程切换。
3. IO选择器(selector)
Selector类是NIO的核心类,通过Selector类来检测多个通道是否有事件发生,如果有就获取事件并对事件进行响应处理。这样就可以通过一个单线程来管理多个通道,这样只有在通道真正有读写事件发生的时候,才会调用函数进行读写,避免多线程之间的上下文切换导致的开销。
4. 通道channel
在前面已经提到,Channel和传统IO中的Stream很相似。虽然很相似,但是有很大的区别,主要区别为:通道是双向的,通过一个Channel既可以进行读,也可以进行写;而Stream只能进行单向操作,通过一个Stream只能进行读或者写;
以下是常用的几种通道:
FileChannel
SocketChanel
ServerSocketChannel
DatagramChannel
通过使用FileChannel可以从文件读或者向文件写入数据;通过SocketChannel,以TCP来向网络
连接的两端读写数据;通过ServerSocketChanel能够监听客户端发起的TCP连接,并为每个TCP连接创建一个新的SocketChannel来进行数据读写;通过DatagramChannel,以UDP协议来向网络连接的两端读写数据。