zoukankan      html  css  js  c++  java
  • Selector#wakeup()

    看thrift源码发现selector.wakeup()方法,通常在selector.select()后线程会阻塞。使用wakeup()方法,线程会立即返回。源码分析应该是用的线程中断实现的。下面是个小demo

    public class TestSelector {
        private static Selector selector;
    
        public static void main(String[] args) throws IOException, InterruptedException {
            startSelectorThread();
            Thread.sleep(2000);
            selector.wakeup();
        }
    
        private static void startSelectorThread(){
            Runnable selectorTask = () -> {
                try{
                    String host = "127.0.0.1";
                    int port = 8888;
                    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
                    serverSocketChannel.configureBlocking(false);
                    SocketAddress socketAddress = new InetSocketAddress(host, port);
                    serverSocketChannel.bind(socketAddress);
                    selector = Selector.open();
                    while(true){
                        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
                        System.out.println("selector start select .....");
                        Set<SelectionKey> selectionKeySet =  selector.selectedKeys();
                        for(Iterator<SelectionKey> iterator = selectionKeySet.iterator(); iterator.hasNext(); ){
                            SelectionKey selectionKey = iterator.next();
                            System.out.println(selectionKey.toString());
                            selectionKeySet.remove(selectionKey);
                            ServerSocketChannel serverSocketChannel1 = (ServerSocketChannel) selectionKey.channel();
                            SocketChannel clientChannel = serverSocketChannel1.accept();
                            clientChannel.configureBlocking(false);
                            clientChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                            iterator.remove();
                        }
    
                        System.out.println("selector end select ....");
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }; //task
            Thread thread = new Thread(selectorTask);
            thread.start();
        }
    }

    我们看下wakeup()注释

    /**
         * Causes the first selection operation that has not yet returned to return
         * immediately.
         *
         * <p> If another thread is currently blocked in an invocation of the
         * {@link #select()} or {@link #select(long)} methods then that invocation
         * will return immediately.  If no selection operation is currently in
         * progress then the next invocation of one of these methods will return
         * immediately unless the {@link #selectNow()} method is invoked in the
         * meantime.  In any case the value returned by that invocation may be
         * non-zero.  Subsequent invocations of the {@link #select()} or {@link
         * #select(long)} methods will block as usual unless this method is invoked
         * again in the meantime.
         *
         * <p> Invoking this method more than once between two successive selection
         * operations has the same effect as invoking it just once.  </p>
         *
         * @return  This selector
         */
        public abstract Selector wakeup();

    可以看出,这个方法会让阻塞的线程立即返回。跟进poll实现的selector的wakeup()方法

    public Selector wakeup() {
            Object var1 = this.interruptLock;
            synchronized(this.interruptLock) {
                if (!this.interruptTriggered) {
                    this.pollWrapper.interrupt();
                    this.interruptTriggered = true;
                }
    
                return this;
            }
        }

    上面可以看出使用的是interrupt()给线程发个中断信号实现的

  • 相关阅读:
    Linux查看进程是否存在及启动或重启
    Leetcode 31.下一个排列 tag数组
    Leetccode 27.移除元素 tag数组
    Leetcode 24:两两交换链表中的节点
    当代90后的焦虑
    典型java面试题
    TD编译环境变量说明
    ubuntu20.04安装TD工具后编译错误
    ssh免密登录在Linux服务器之间的设置
    ubuntu20.04导航栏放到底部
  • 原文地址:https://www.cnblogs.com/luckygxf/p/9395297.html
Copyright © 2011-2022 走看看