离上次发布文章已过去好几个月,说好的积累和分享都烟消云散。似乎忙碌从未终止过,加班成为常态,甚至阅读都需要更琐碎的时间。
目录
NIO(一、概述)
NIO(二、Buffer)
NIO(三、Channel)
NIO(四、Selector)
概述
JavaNIO(new IO),1.4版本引入的新的IO API。从表现来看,NIO优化了更多的应用场景。在1.7版本NIO做了一次升级,引入了更多的特性,例如AIO
说起NIO,似乎有很多相关的概念,诸如同步(/异步)阻塞(/非阻塞),Reactor(/Proactor)模式,把这些概念清晰明白的说出来并非一日之功。
与IO有何区别
这是某文件的一段文本
Hello
World
简单的IO操作就像下面这样:
InputStream input = new FileInputStream(dir);
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line1 = reader.readLine(); //"Hello"
String line2 = reader.readLine(); //"World"
那么NIO操作简单事例:
FileInputStream fis = new FileInputStream(dir);
//创建通道
FileChannel channel = fis.getChannel();
//分配缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
channel.read(buffer);
String txt = Charset.forName("utf-8").newDecoder().decode(buffer).toString();
可以肯定的是,两种工作方式并不同。
比较上面两份代码,我们会发现,IO的操作是直接操作流的,而NIO却是操作缓冲区,相比较操作流,操作缓冲区将会更加自由灵活。
此外,需要注意的是,使用Java IO时,当执行 reader.readLine() 时候,意味着当前的线程呈阻塞状态,直到该行读取结束。
显然,NIO的选择器允许单独的线程来管理多个通道,尽力利用一个线程的资源处理多个连接,这就是多路复用。因为这个机制,线程在空闲的状态下,不会因为某个通道等待而阻塞另一个通道。当然,NIO同样也提供了Asynchronous IO(异步IO),不论数据从通道到缓冲区还是缓冲区到通道,任何一个空闲的时候,线程都可以做其他事情。
那么什么时候使用NIO呢?做一个比喻,假如线程是一个水桶的话,你去一个水龙头接水,那么此时你可以使用Java IO,但如果水龙头的水时有时无不说,水流还小,那么你可能会用这个水桶同时接多个水龙头,那么这时候,你使用的就应该是Java NIO。
组成部分
- Channels
- Buffers
- Selectors
NIO API最核心就是这三个部分,Channels意指通道,数据从通道(Channel)开始,流入缓冲区(Buffer),或者从缓冲区流入通道,选择器(Selector)存在的意义便是监听多个通道的事件,让线程处理。
(未完待续!)