了解nio的selector

学习nio,最费解是selector,为了了解这个东西,花了不少时间看博文。为此我将我的学习理解过程记录了下来

1、什么是selector?

Selector选择器,channel可以在Selector上注册,并绑定选择键SelectorKey,同时可以添加一个附加的对象进行标志。他能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。

2、那些channel可以在selector上注册?

FileChannel,针对文件IO的Channel是不支持selector的,selector需要实现SelectableChannel接口的channel,在jdk的继承中有如下几个类:DatagramChannel, Pipe.SinkChannel, Pipe.SourceChannel, ServerSocketChannel, SocketChannel

3、练习

网上案例基本是针对ServerSocketChannel建立的selector,练习当然不能只按别人的路子走,我在上面几个类中选择了DatagramChannel作为练习的channel。

/**
 *
 * @author rain-bean
 *
 */
public class CustomerTest {
    private static Selector selector;
    private static DatagramChannel channel;
    private static DatagramChannel channel2;

    public static void openChanel() throws IOException{

        channel = DatagramChannel.open();
        channel.socket().bind(new InetSocketAddress(9999));
        //与Selector一起使用时,Channel必须处于非阻塞模式下
        channel.configureBlocking(false);
        //通过open()方法找到Selector
        selector = Selector.open();

        SelectionKey key = channel.register(selector, SelectionKey.OP_READ); //经检测DatagramChannel并不能注册所有的key
        System.out.println("等待连接");
    }

    //监听
    private static void listen() throws IOException{
        boolean bl = true;
        while(bl){
            // 选择一组键,并且相应的通道已经打通。阻塞线程
            selector.select();

            //获取注册的key
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            //处理感兴趣的key
            while(iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();

                if(selectionKey.isReadable()){
                    ByteBuffer buffer =ByteBuffer.allocate(60);
                    channel.receive(buffer);
                    System.out.println("读取:"+ new String(buffer.array(),"utf-8")); //中文转码
                    System.out.println("文件读取完毕");
                    bl = false;
                }
            }
        }
    }

    /**
     * 发送数据
     * @throws IOException
     */
    private static void send() throws IOException{
        channel2 =DatagramChannel.open();
        ByteBuffer buffer = ByteBuffer.wrap("雨水打在窗台的铝架上,哔哔哒哒的".getBytes("utf-8"));  //中文需要转码
        channel2.send(buffer, new InetSocketAddress("localhost",9999));
    }  

    public static void main(String[] args) throws IOException{
        CustomerTest.openChanel();
        //先send后listen,因为selector会阻塞,当然最好是另起一个线程,分服务和客户端
        CustomerTest.send();
        CustomerTest.listen();
        channel.close();
        channel2.close();
    }

}

4、总结

经过练习对selector加深了解,也发现并不是channel可以随意注册事件,他的应用应该是为了多路复用传输,而不是为了对文件的不阻塞操作。实例可以进一步深化,编写服务和客户端进行多channel的操作。时间有限,及时行乐,我就不写了。

最后理解错误之处请之处。

时间: 2024-10-21 23:28:53

了解nio的selector的相关文章

利用NIO的Selector处理服务器-客户端模型

内容:这是一个简单的服务器-客户端模型,利用了NIO的Selector来处理多个管道.至于Selector的介绍看这里 NIOServer: public class NIOServer { public static void main(String[] args) throws IOException, InterruptedException { Selector selector = Selector.open(); ServerSocketChannel serverSocketCha

Java NIO 选择器(Selector)的内部实现(poll epoll)

http://blog.csdn.net/hsuxu/article/details/9876983 之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识: Java NIO中的选择器依赖操作系统内核的这些系统调用,我们这里只讲解与linux内核相关的NIO实现,当然,windows或其他操作系统实现大体上是类似的,相信大家也可以触类旁通. 那么,本文从这里将从简到难,一步一步为大家讲解选择器的点点滴滴吧. 选择器的宏观理解“有这么一种检查员,她工作在养鸡场,每天的工

Java NIO类库Selector机制解析--转

一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: Buffer:包含数据且用于读写的线形表结构.其中还提供了一个特殊类用于内存映射文件的I/O操作. Charset:它提供Unicode字符串影射到字节序列以及逆映射的操作. Channels:包含socket,file和pipe三种管道,都是全双工的通道. Selector:多个异步I/O操作集

Java NIO 之 Selector 练习

目的:本编文章主要想分享一下NIO方面的知识,由于最近几天工作不忙,趁机学习了下Java NIO Selector的相关知识:主要是实践操作的:具体的理论知识,可以参考网上的文章. 测试用例主要有三种方式: 其实,是服务器端的逻辑不变,客户端有三种方式而已. 服务器端:2个selector + channel, 客户端:一个channel 服务器端:2个selector + channel, 客户端:多个channel(多线程方式) 服务器端:2个selector + channel, 客户端:

NIO组件 Selector(选择器)

简介 使用Selector(选择器), 可以使用一个线程处理多个客户端连接. Selector 能够检测多个注册的通道上是否有事件发生(多个Channel以事件的方式可以注册到同一个Selector), 如果有事件发生, 便获取事件然后针对每个事件进行相应的处理.这样就可以只用一个单线程去管理多个通道, 也就是管理多个连接和请求. 只有在连接有读写事件发生时, 才会进行续写, 就大大地减少了系统开销, 并且不必为每个连接都创建一个线程, 不用去维护多个线程. 避免了多线程之间的上下文切换导致的开

Java NIO之Selector

选择器是JavaNIO重磅推出的一个概念:在旧有的系统中为了跟踪多端口消息,需要为每一个端口配备一个线程做监听:但是有了selector就不需要了,一个Selector可以管理一众渠道(channel). 选择器的本质就是:让监听的工作由选择起来做:它会定时执行来获取注册到他那里的渠道是否已经准备就绪,比如socketServerChannel是否有新的消息过来(是否做好了accept的准备):然后他会把这个channel放入到一个集合中(SelectedKeys),遍历一遍之后,就可以,你就可

Java之NIO(二)selector socketChannel

上篇文章对NIO进行了简介,对Channel和Buffer接口的使用进行了说明,并举了一个简单的例子来说明其使用方法. 本篇则重点说明selector,Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 与selector联系紧密的是ServerSocketChannel和SocketChannel,他们的使用与上篇文章描述的FileChannel的使用方

Java NIO (6) Selector

Java NIO Selector A Selector is a Java NIO component which can examine one or more NIO Channel's, and determine which channels are ready for e.g. reading or writing. This way a single thread can manage multiple channels, and thus multiple network con

JAVA NIO 之 Selector 组件

NIO 重要功能就是实现多路复用.Selector是SelectableChannel对象的多路复用器.一些基础知识: 选择器(Selector):选择器类管理着一个被注册的通道集合的信息和它们的就绪状态. 可选择通道(SelectableChannel):这个抽象类提供了实现通道的可选择性所需要的公共方法.它是所有支持就绪检查的通道类的 父类.例如:ServerSocketChannel.SocketChannel.可选择通道可以被注册到选择器上. 选择键(SelectionKey):选择键封