1.背景:java.nio相对于java.io中的一些缺点,比如block服务,传送效率,提供了一些新的特点比如多线程的存取安全性、提供缓存buffered、字符集编码解决方案以及一种新的I/O抽象(实现了channel接口)。 原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。
2.本质上用channel和buffer来实现数据的读写。buffer是I/O的中转地,channel是源头或目的地,是buffer对象的唯一接口 。
通过一个小例子可以看到,相对于I/O,NIO进行了buffer、channel的一些中间件的通道设置,先设置一个ByteBuffer,通过一个FileChannel的read()方法将FileChannel的data读取进buffer里面,然后再通过FileChannel的write方法将buffer中的data读取进FileChannel中。之后FileChannel会自动将数据写进FileOutputStream继而写进File中。此处注意:在读取data进buffer之前要进行Buffer的clear,写进FileChannel之前,要进行Buffer的Flip。关于clear的机制:Buffer的属性有position、limit、capacity,读的模式下,比如读取一个CharBuffer,是从position的位置开始读取,然后读取到limit的位置,所以一般读取之前,可以调用Buffer.clear()方法,将position设置为0,limit设置为capacity的值。注意clear方法只是改变缓冲区的索引,并非进行清空。而flip恰恰相反,flip是为了将buffer调整为数据传出状态,将limit设置为position的当前值,将position设置为0.另外还有rewind方法,将数据的positon设置为0,与flip的区别是limit不变。
3.比较nio与io中的区别。在面向流的IO中,所有的数据都是直接读到stream中,而在nio中所有的数据都是用缓冲区处理的,任何情况下访问数据都是用缓冲区处理的,缓冲区可以是一个数组,通常是字节数组,但它不仅仅是数组,它提供了数据访问机制。Channel是一个对象,用它可以读取或写入数据,与stream最大的区别就是它不仅仅能够写还能够读,它是双向的。
4.对于网络通讯的应用,获取一个SocketAddress,然后得到一个SocketChannel,然后用SocketChannel的write,再用buffer完成存取。
5.关于阻塞式的改进,以前的阻塞式比如accept会阻塞,线程需要每隔一定时间进行上下文切换,找到目的地结果,而非阻塞里面线程都在休眠,只有在真正外部环境准备好的情况下才会唤醒。原理是由一个专门的线程来处理所有的IO事件,并负责分发。事件驱动机制:事件到的时候触发,而不是同步的监测事件。线程之间通讯是通过wait,notify等方式进行。
6.Slector,异步IO的核心类,它能检测一个或多个通道上的事件,并将事件分发出去,使用一个selector线程能监听多个通道上的事件,并不需要为一个channel分配一个线程。