Java NIO 技术要点

发布时间:2016-12-6 18:13:56 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"Java NIO 技术要点",主要涉及到Java NIO 技术要点方面的内容,对于Java NIO 技术要点感兴趣的同学可以参考一下。

问题:系统运行瓶颈,I/O读写,因为打开一个I/O通道以后,read()将一直等待在端口一边读取字节内容,如果没有内容进来,read()也是傻傻的等,这会影响我们程序继续做其他事情,那么改进做法就是开设线程,让线程去等待,但是这样做也是相当耗费资源的。 Java NIO解决方案:采用非阻塞技术,采取Reactor模式或者观察者模式,等到内容进来再自动通知,而不必死等,使I/O读写通畅,不堵塞了。 具体原理描述:NIO有一个主要的类selector,它类似一个观察者,只要我们把需要探知的socketChannel告知selector,我们可以安心干其他事情,当有事件发生时,它会消息通知我们,传回一组selectionKey,根据这个key可以获得刚刚注册的socketChannel,然后就可以从这个Channel中读取数据。 Selector的内部原理:实际上是对所有channel做一个轮询访问,一旦发现有事件,比如数据来了,它就会通知报告,交出一把钥匙。 以下是测试代码 /** * Start server * * @throws IOException */ public void startServer() throws IOException { int channels = 0; int nKeys = 0; // int currentSelector = 0; // Use selector Selector selector = Selector.open(); ServerSocketChannel ssc = ServerSocketChannel.open(); InetSocketAddress address = new InetSocketAddress(InetAddress.getLocalHost(), 9000); // Bind address ssc.socket().bind(address); // Non-blocking model ssc.configureBlocking(false); // Register SelectionKey sk = ssc.register(selector, SelectionKey.OP_ACCEPT); printKeyInfo(sk); // For each while (true) { debug("Starting select..."); // Some thing happened. return a set of keys which channels are ready for I/O nKeys = selector.select(); if(nKeys > 0) { debug("Number of keys after select operation: " + nKeys); //Selector传回一组SelectionKeys Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> i = selectedKeys.iterator(); while(i.hasNext()) { sk = (SelectionKey) i.next(); printKeyInfo(sk); debug("Nr Keys in selector: " +selector.keys().size()); // Remove i.remove(); if(sk.isAcceptable()) { Socket socket = ((ServerSocketChannel)sk.channel()).accept().socket(); SocketChannel sc = socket.getChannel(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ |SelectionKey.OP_WRITE); System.out.println(++channels); } else { debug("Channel not acceptable"); } } } else { debug("Select finished without any keys."); } } } /** * Debug * * @param str */ private static void debug(String str) { System.out.println("NIO Test: " + str); } /** * Print key info * * @param sk */ private static void printKeyInfo(SelectionKey sk) { StringBuffer sb = new StringBuffer(); sb.append("Att: " + (sk.attachment() == null ? "no" : "yes")); sb.append(", Read: " + sk.isReadable()); sb.append(", Acpt: " + sk.isAcceptable()); sb.append(", Cnct: " + sk.isConnectable()); sb.append(", Wrt: " + sk.isWritable()); sb.append(", Valid: " + sk.isValid()); sb.append(", Ops: " + sk.interestOps()); debug(sb.toString()); }

上一篇:sdut2125 串结构练习——字符串匹配(strstr求子串)
下一篇:Ejabberd源码解析前奏--集群

相关文章

相关评论