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()给线程发个中断信号实现的
Selector#wakeup()的更多相关文章
- Java NIO之选择器Selector
在单独的线程中,检查多个通道是否可以进行IO操作. Selector创建:静态工厂方法创建 Selector selector = Selector.open(); 注册通道 channel.conf ...
- java的nio之:java的nio系列教程之selector
一:Java NIO的selector的概述===>Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程 ...
- Java基础知识强化之IO流笔记77:NIO之 Selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 1. ...
- Java NIO类库Selector机制解析(下)
五. 迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/O要设计成这个样子?如果说老的I/O不能多路复用,如下图所示,要开N多的线程去挨个侦听每一个Channel ...
- NIO组件Selector详解
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...
- NIO组件Selector工作机制详解(下)
转自:http://blog.csdn.net/haoel/article/details/2224069 五. 迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/ ...
- Java NIO——Selector机制源码分析---转
一直不明白pipe是如何唤醒selector的,所以又去看了jdk的源码(openjdk下载),整理了如下: 以Java nio自带demo : OperationServer.java Oper ...
- Java NIO类库Selector机制解析--转
一. 前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...
- NIO(四、Selector)
目录 NIO(一.概述) NIO(二.Buffer) NIO(三.Channel) NIO(四.Selector) Selector 前面两个章节都描述了Buffer和Channel,那这个章节就描述 ...
随机推荐
- sonar阻断级别错误(block)简单汇总
1.代码里面包含PASSWORD.PWD 'PWD' detected in this expression, review this potentially hardcoded credential ...
- CSS动态定位
$(document).ready(function(){ $('body').on('click', '#start_timer', function() { var laydate = $(&qu ...
- 【maven】maven 子项目如何使用父项目的jar包
如果父pom中使用的是 <dependencies>....</dependencies> 方式, 则子pom会自动使用pom中的jar包 如果父pom使用 <depen ...
- os模块详解
python编程时,经常和文件.目录打交道,这是就离不了os模块.os模块包含普遍的操作系统功能,与具体的平台无关.以下列举常用的命令 1. os.name——判断现在正在实用的平台,Windows ...
- PL/SQL数据库开发那点事
PL/SQL数据库开发那点事-->编程,存储程序 在SQL*plus 中编写PL/SQL程序,并在SQL*plus 中执行它, PL/SQL块的代码就存放在SQL*plus的缓冲区中.如果在SQ ...
- python 入门级教你如何拿到小姐姐微信
第一题: 首先错误的思路,首先找出 707829217/2+1 里面的所有奇数,然后再利用两个for,来判断 import math def func_get_prime(n): return ...
- 提交app时候遇到IDFA警告
1.最近提交app时候遇到如下问题,解决方案: Everything has come to its usual state now. Simply upload your binary as you ...
- SpringBoot 启动的时候提示 Field *** in *** required a bean named 'entityManagerFactory' that could not be found.
错误截图 后面发现原来和入口类代码有关. //@SpringBootApplication(scanBasePackages = {"org.jzc.odata.cboard",& ...
- NSInvocation 调用block clang代码转换c++
NSInvocation 调用block cpp 转换 fatal error: 'UIKit/UIKit.h' file not found https://blog.csdn.net/yst199 ...
- rinetd做代理!redis做代理使外网直接远程连接
Centos7下Rinetd安装与应用 Linux下做地址NAT有很多种方法.比如haproxy.nginx的4层代理,linux自带的iptables等都能实现.haproxy.nginx就不说 ...