Java NIO
NIO
NIO与IO
主要的区别
区别见下表:
IO |
NIO |
面向流(输入流/输出流) |
面向缓冲区(各种缓冲区,除了布尔类型之外其他的基本数据类型都有缓冲区跟其对应) |
阻塞IO |
非阻塞IO |
无选择 |
选择器 |
- 流与缓冲区
IO面向流,NIO面向缓冲区,面向流意味着每次从流中读取一个字节或多个字节,直到把所有字节读完,没有缓冲的地方,另外,流中的数据不能前后移动。如果想要灵活得达到我们得目的,需要我们手动建立一个数组缓冲区去实现。
Java NIO,数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
- 阻塞与非阻塞
IO的各种流都是阻塞的,也就是一个线程在read()或是write时线程是等待的,直到有数据可读取或是所有数据都一写完毕,这个线程在此期间就不能做任何事情了。
NIO是非阻塞IO:
阻塞读:一个线程从某个通道发送请求读数据,但是它只能得到目前可用的数据,若目前没有数据可用时,就什么也不会获取,而不是保持线程阻塞,直到数据可以读之前,在这期间这个线程可以做其他的任何事情。
非阻塞写:一个线程请求写入一些数据到某通道,不需要等待它完全写入,这个线程就可以处理其他的任务。线程通常将非阻塞IO的空闲时间处理其他通道的IO操作。
一个线程可以管理多个输出输出通道,也就时channel。
- 选择性
NIO通过选择器使得一个线程可以管理多个通道,将多个通道注册使用一个选择器,一个线程就可以“选择”不同的通道。
NIO和IO的选择
NIO可只使用一个(或几个)单线程管理多个通道(网络连接或文件),但付出的代价是解析数据可能会比从一个阻塞流中读取数据更复杂。
如果需要管理同时打开的成千上万个连接,这些连接每次只是发送少量的数据,例如聊天服务器,实现NIO的服务器可能是一个优势。同样,如果需要维持许多打开的连接到其他计算机上,如P2P网络中,使用一个单独的线程来管理你所有出站连接,可能是一个优势。
如果有少量的连接使用非常高的带宽,一次发送大量的数据,也许典型的IO服务器实现可能非常契合。