美文网首页
选择器Selector (持续更新中)

选择器Selector (持续更新中)

作者: sunpy | 来源:发表于2018-08-26 13:37 被阅读9次

介绍

引用的问题 -> BIO本身关心的是读写的过程,如果可以直接读写,就读写;不允许就阻塞读写。Java NIO将上面的读写拆分为准备读写和真正读写两个过程。而java NIO的这两个过程就是通过选择器实现的。所以选择器多了等待就绪,选择执行就绪任务的功能。

选择器执行过程

  1. 通过open方法程序创建一个系统默认的选择器。
  2. 使用register方法将一个或者多个可选择通道注册到选择器上(至于注册上去的可选择通道的类型SelectionKey选择键来表示)。
  3. SelectionKey选择键会标记每个注册到选择器上的通道,然后通过SelectionKey的isReadable、isWritable等方法判断通道是否可读可写;然后就要真正去读写了。
  4. 使用选择器Selector调用方法select,然后更新选择器键集。至于发生阻塞,是一直阻塞还是阻塞一段时间还是阻塞立即返回就体现在select()、select(time)、selectNow()方法上了。
  5. 如果通过选择键找到了对应的就绪通道,然后剩下就是缓冲区上读写操作等。

选择键

选择键是选择通道在选择器上的一个注册标记。


1.png

例子

客户端:

public class MyNIOClient {

    public static void main(String[] args) throws IOException {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));
        // 完成套接字通道的连接过程
        if (socketChannel.finishConnect()) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            buffer.put("sunpy".getBytes());
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
        }
        socketChannel.close();
    }
}

服务端:

public class MyNIOServer {

    public static void main(String[] args) throws IOException {
        ServerSocketChannel seChannel = ServerSocketChannel.open();
        seChannel.configureBlocking(false);
        seChannel.bind(new InetSocketAddress("127.0.0.1", 9999));
        Selector selector = Selector.open();
        seChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        while (selector.select() > 0) {
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext()) {
                SelectionKey key = it.next();
                // 此键的通道是否已准备好接受新的套接字连接
                if (key.isAcceptable()) {
                    // 返回为之创建此键的通道
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                     // 接受到此通道套接字的连接,如果有返回套接字通道,将阻塞
                    SocketChannel clientChannel = channel.accept();
                    // 配置为非阻塞
                    clientChannel.configureBlocking(false);
                    // 注册到selector,等待连接 
                    clientChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel clientChannel = (SocketChannel) key.channel(); 
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    clientChannel.read(buffer);
                    buffer.flip();
                    
                    while (buffer.hasRemaining()) {
                        System.out.print((char) buffer.get());
                    }
                    
                    buffer.clear();
                }
                // 将键集中操作过的键移出
                it.remove();
            }
        }
    }
}

结果:


3.jpg

相关文章

  • 选择器Selector (持续更新中)

    介绍 引用的问题 -> BIO本身关心的是读写的过程,如果可以直接读写,就读写;不允许就阻塞读写。Java NIO...

  • JQuery教程之入门基础

    语法 $(selector).action() selector:选择器,类似css中的选择器 比如: $('.b...

  • jquery学习

    $("selector")支持所有css选择器 $("selector",dom)从指定dom中根据选择器查找元素...

  • Selector

    Selector中的各种状态详解 Android进阶之路 - selector状态选择器 selector原理简述...

  • Java NIO学习笔记-Selector

    Selector选择器是什么 Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓...

  • Android 自定义形状

    1. selector的使用 selector是android中的一种选择器,用selector设置控件的背景,可...

  • Java NIO Selector

    Java NIO Selector Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能...

  • Selector syntax sugar

    Selector(方法选择器)在target-action模式中必不可少的,通过Selector可以找到指定的方法...

  • pyquery

    什么是pyquery? find(selector) : 使用css选择器查找filter(selector) :...

  • Java Nio选择器Selector

    Selector Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸...

网友评论

      本文标题:选择器Selector (持续更新中)

      本文链接:https://www.haomeiwen.com/subject/vbkbiftx.html