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