这两天一直在看关于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的知识的话,我在网上看到了几篇不错的博客
Java NIO API详解:
http://www.blogjava.net/19851985lili/articles/93524.html