Java NIO学习(1)
Java NIO学习(一)
测试代码:
这两天一直在看关于Java NIO方面的论文、博客、教程什么的。但是总感觉理解的不深刻。看来这么多了,就展示下自己的学习成果吧。如果有错误欢迎指正。
关于java NIO的介绍我这里就不赘述了,网上随便一搜就一大堆!
1
java NIO工具包中有三个核心成员。分别是Buffer(缓冲器),Channel(通道),Selector(选择器)和SelectionKey(选择键),下边就先简单说下这三个成员。
(1).Buffer(缓冲器)
Buffer类是一个抽象类,它有分别对应着java中7中数据类型的子类,分别是,ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、LongBuffer、IntBuffer、ShortBuffer。每个Buffer相当于一个数据容器,可以把他们看作内存中的一个数组。Buffer类的核心是一块内存区,可以直接对其执行与内存有关的操作,利用操作系统特性和能力提高改善传统I/O的性能。
(2).Channel(通道)
Channel是NIO工具包中的创新点,是(Buffer)缓冲器和I/O服务之间的通道,具有双向性,既可以读入也可以写出,可以更高效的传递数据。这里主要说下ServerSocketChannel和SocketChannel,它们都继承了SelectableChannel,是可选择的数据通道,分别可以工作在同步和异步两种方式下。当通道工作在同步方式时,它的功能和编程方法与传统的ServerSocket、Socket相似;当通道工作在异步方式时,进行输入输出处理不必等到输入输出完毕才返回,并且可以将其感兴趣的(如:接受操作、连接操作、读出操作、写入操作)事件注册到Selector对象上,与Selector对象协同工作可以更有效率的支持和管理并发的网络套接字连接。
(3).Selector(选择器)SelectionKey(选择键)
个类Buffer是数据的容器对象;个类Channel实现在个类Buffer与个类I/O服务之间传输数据。Selector是实现并发型非阻塞I/O核心,各中可选择的通道将其感兴趣的事件注册到Selector对象上,Selector在一个循环中不断轮询监视这些注册在上边的Socket通道。SelectionKey类则封装了SelectableChannel对象在Selector中注册信息。当Selector监测到在某个注册的SelectionChannel上发生了感兴趣的事件,自动激活产生一个SelectionKey对象,在这个对象中记录了哪一个SelectionChannel上发生了哪些种事件,通过对被激活的SelectionKey的分析,外界可以知道每个SelectableChannel发生的具体事件类型,进行相应的处理。
2.一个简单的Java NIO实例
下面给出一个简单的NIO实例。
package com.baz.server; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.util.Iterator; import java.util.Set; public class NIODemo { private int port; private Selector selector; public NIODemo(int port) throws IOException { //打开服务器套接字通道 ServerSocketChannel serverChannel = ServerSocketChannel.open(); //将服务器设置为非阻塞型 serverChannel.configureBlocking(false); // 检索与此通道关联的服务器套接字 ServerSocket serverSocket = serverChannel.socket(); //进行服务的绑定 serverSocket.bind(new InetSocketAddress(port)); //初始化Selector对象 selector = Selector.open(); //将服务器channel注册到Selector对象,并指出服务器Channel所感兴趣的事件为可接受请求 serverChannel.register(selector, SelectionKey.OP_ACCEPT); } public void run() throws IOException{ while(true){ // 选择一组键,并且相应的通道已经打开 selector.select(); // 返回此选择器的已选择键集。 Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); if(selectionKey.isAcceptable()){ doAcceptableEvent(); } else if(selectionKey.isReadable()){ doReadableEvent(); } else if(selectionKey.isWritable()){ doWriteableEvent(); } } } } private void doWriteableEvent() { //dosomething } private void doReadableEvent() { // dosomething } private void doAcceptableEvent() { // dosomething } }
测试代码:
import java.io.IOException; import com.baz.server.NIODemo; public class DemoTest { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { NIODemo server = new NIODemo(2000); server.run(); } }程序运行起来了,但是什么东西也没有输出。这只是一个最简单服务器程序。
要更多了解Java NIO的知识的话,我在网上看到了几篇不错的博客
NIO揭秘:http://my.oschina.net/zhangya/blog/30480
Java NIO API详解:http://www.blogjava.net/19851985lili/articles/93524.html
http://weixiaolu.iteye.com/blog/1479656