- 浏览: 2203357 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
1.概念
GlobalEventExecutor是具备任务队列的单线程事件执行器,其适合用来实行时间短,碎片化的任务
2.inEventLoop方法
判断当前执行代码是否在同一个线程,有两种情况
3.测试代码
3.1
输出结果:
执行的线程是同一个线程,在执行线程中, inEventLoop为true
3.2
每隔1秒钟添加任务,将会看到线程都是新创建的,因为线程执行完毕后会自动退出
输出结果
4.源码分析
启动线程的逻辑:当前没有线程且线程没有在任务执行状态
5.DefaultPromise的实现
本质是使用EventExecutor的execute方法,将通知方法放到异步线程队列中,所以其回调也是在EventExecutor的线程中执行
回调调用堆栈
测试代码:
/** * Single-thread singleton {@link EventExecutor}. It starts the thread automatically and stops it when there is no * task pending in the task queue for 1 second. Please note it is not scalable to schedule large number of tasks to * this executor; use a dedicated executor. */ public final class GlobalEventExecutor extends AbstractScheduledEventExecutor { }
GlobalEventExecutor是具备任务队列的单线程事件执行器,其适合用来实行时间短,碎片化的任务
public final class GlobalEventExecutor extends AbstractScheduledEventExecutor { //单例对象 public static final GlobalEventExecutor INSTANCE = new GlobalEventExecutor(); //维护的任务队列 final BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>(); ScheduledFutureTask.deadlineNanos(SCHEDULE_QUIET_PERIOD_INTERVAL), -SCHEDULE_QUIET_PERIOD_INTERVAL); //线程工厂 final ThreadFactory threadFactory = new DefaultThreadFactory(DefaultThreadFactory.toPoolName(getClass()), false, Thread.NORM_PRIORITY, null); //一个循环运行的执行器 private final TaskRunner taskRunner = new TaskRunner(); //标记当前线程是否启动 private final AtomicBoolean started = new AtomicBoolean(); //运行中的线程 volatile Thread thread; }
2.inEventLoop方法
判断当前执行代码是否在同一个线程,有两种情况
- 第一次没有异步线程,则创建新线程
- 若在非当前运行线程中添加任务,判断异步线程是否在执行,如果没有则创建新的线程(原线程已经执行完毕)
3.测试代码
3.1
{ for (int i=0;i<5;i++) { Future<Integer> future=GlobalEventExecutor.INSTANCE.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("eventExecutor threadId:"+Thread.currentThread().getId()+ " inEventLoop:"+GlobalEventExecutor.INSTANCE.inEventLoop()); return 1; } }); System.out.println("threadId:"+Thread.currentThread().getId()+ " inEventLoop:"+GlobalEventExecutor.INSTANCE.inEventLoop()); } }
输出结果:
执行的线程是同一个线程,在执行线程中, inEventLoop为true
threadId:1 inEventLoop:false eventExecutor threadId:12 inEventLoop:true threadId:1 inEventLoop:false threadId:1 inEventLoop:false threadId:1 inEventLoop:false threadId:1 inEventLoop:false eventExecutor threadId:12 inEventLoop:true eventExecutor threadId:12 inEventLoop:true eventExecutor threadId:12 inEventLoop:true eventExecutor threadId:12 inEventLoop:true
3.2
每隔1秒钟添加任务,将会看到线程都是新创建的,因为线程执行完毕后会自动退出
{ for (int i=0;i<5;i++) { Future<Integer> future=GlobalEventExecutor.INSTANCE.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { System.out.println("eventExecutor threadId:"+Thread.currentThread().getId()+ " inEventLoop:"+GlobalEventExecutor.INSTANCE.inEventLoop()); return 1; } }); Thread.sleep(1000); System.out.println("threadId:"+Thread.currentThread().getId()+ " inEventLoop:"+GlobalEventExecutor.INSTANCE.inEventLoop()); } }
输出结果
eventExecutor threadId:12 inEventLoop:true threadId:1 inEventLoop:false eventExecutor threadId:13 inEventLoop:true threadId:1 inEventLoop:false eventExecutor threadId:14 inEventLoop:true threadId:1 inEventLoop:false eventExecutor threadId:15 inEventLoop:true threadId:1 inEventLoop:false eventExecutor threadId:16 inEventLoop:true threadId:1 inEventLoop:false
4.源码分析
启动线程的逻辑:当前没有线程且线程没有在任务执行状态
@Override public void execute(Runnable task) { if (task == null) { throw new NullPointerException("task"); } addTask(task); if (!inEventLoop()) { startThread(); } } private void startThread() { if (started.compareAndSet(false, true)) { Thread t = threadFactory.newThread(taskRunner); // Set the thread before starting it as otherwise inEventLoop() may return false and so produce // an assert error. // See https://github.com/netty/netty/issues/4357 thread = t; t.start(); } } final class TaskRunner implements Runnable { @Override public void run() { for (;;) { Runnable task = takeTask(); if (task != null) { try { task.run(); } catch (Throwable t) { logger.warn("Unexpected exception from the global event executor: ", t); } if (task != quietPeriodTask) { continue; } } Queue<ScheduledFutureTask<?>> scheduledTaskQueue = GlobalEventExecutor.this.scheduledTaskQueue; // Terminate if there is no task in the queue (except the noop task). if (taskQueue.isEmpty() && (scheduledTaskQueue == null || scheduledTaskQueue.size() == 1)) { // Mark the current thread as stopped. // The following CAS must always success and must be uncontended, // because only one thread should be running at the same time. boolean stopped = started.compareAndSet(true, false); assert stopped; // Check if there are pending entries added by execute() or schedule*() while we do CAS above. if (taskQueue.isEmpty() && (scheduledTaskQueue == null || scheduledTaskQueue.size() == 1)) { // A) No new task was added and thus there's nothing to handle // -> safe to terminate because there's nothing left to do // B) A new thread started and handled all the new tasks. // -> safe to terminate the new thread will take care the rest break; } // There are pending tasks added again. if (!started.compareAndSet(false, true)) { // startThread() started a new thread and set 'started' to true. // -> terminate this thread so that the new thread reads from taskQueue exclusively. break; } // New tasks were added, but this worker was faster to set 'started' to true. // i.e. a new worker thread was not started by startThread(). // -> keep this thread alive to handle the newly added entries. } } } }
5.DefaultPromise的实现
本质是使用EventExecutor的execute方法,将通知方法放到异步线程队列中,所以其回调也是在EventExecutor的线程中执行
private void notifyListeners() { EventExecutor executor = executor(); if (executor.inEventLoop()) { final InternalThreadLocalMap threadLocals = InternalThreadLocalMap.get(); final int stackDepth = threadLocals.futureListenerStackDepth(); if (stackDepth < MAX_LISTENER_STACK_DEPTH) { threadLocals.setFutureListenerStackDepth(stackDepth + 1); try { notifyListenersNow(); } finally { threadLocals.setFutureListenerStackDepth(stackDepth); } return; } } safeExecute(executor, new Runnable() { @Override public void run() { notifyListenersNow(); } }); } private static void safeExecute(EventExecutor executor, Runnable task) { try { executor.execute(task); } catch (Throwable t) { rejectedExecutionLogger.error("Failed to submit a listener notification task. Event loop shut down?", t); } }
回调调用堆栈
测试代码:
Promise<Integer> promise=GlobalEventExecutor.INSTANCE.newPromise(); promise.addListener(new GenericFutureListener<Future<? super Integer>>() { @Override public void operationComplete(Future<? super Integer> future) throws Exception { System.out.println("threadId:"+Thread.currentThread().getId()); System.out.println("operationComplete"); } }); System.out.println("threadId:"+Thread.currentThread().getId()); promise.trySuccess(2);
发表评论
-
小程序textarea完美填坑
2020-07-07 16:09 529相信做微信小程序的码友们都被textarea这个原生组件坑过 ... -
Nginx+Https自己敲命令生成证书
2020-05-18 09:35 955一、准备 环境:centos6.8 ... -
https证书生成环境搭建配置(基于Tomcat和Nginx)
2020-04-24 11:06 828一、基于Tomcat、JDK内置密钥工具: 1、生成服务端证 ... -
史上最强Tomcat8性能优化
2019-11-01 21:41 910授人以鱼不如授人以渔 ... -
SpringBoot配置HTTPS,并实现HTTP访问自动转HTTPS访问
2019-10-07 09:13 5661.使用jdk自带的 keytools 创建证书 打开cmd ... -
Spring Boot工程集成全局唯一ID生成器 UidGenerator
2019-09-16 09:04 861概述 流水号生成器(全局唯一 ID生成器)是服务化系统的基础 ... -
CentOS7下Redis的安装与使用
2019-08-17 11:45 612一、手动安装过程 1、准备工作(安装gcc依赖) yum ... -
Nginx与tomcat组合的简单使用
2019-08-17 10:05 444配置tomcat跳转 请求http出现400的时候在这里配置 ... -
linux下lvs+keepalived安装配置
2019-07-10 14:20 466keepalived主机:192.168.174. ... -
使用Docker搭建Tomcat运行环境
2019-02-08 21:32 4941 准备宿主系统 准备一 ... -
Netty4转发服务的实现方案
2019-02-06 15:03 1146如果用Netty做转发服务(不需要同步应答),Netty中有一 ... -
java手机号归属地查询
2018-12-25 17:16 750所需的包:carrier-1.75.jar 、geocoder ... -
基于Netty4的HttpServer和HttpClient的简单实现
2018-10-17 20:02 700Http 消息格式: Http request: Met ... -
javafx : 支持使用微调(spinner)控制的数字的文本框(NemberTextField)
2018-10-16 00:00 1100最近花了一些时间学习javaFX, 要更深入地理解新GUI包, ... -
我的Java(定制你的Java/JavaFX Runtime)
2018-10-12 23:29 681最新的JDK 11发布了,撒花 新版本的JDK终于有了ope ... -
javaFX的几个新特性,让swing彻底过时
2018-10-12 22:42 670首先声明,Java的GUI曾经 ... -
mac os系统用install4j把jar包生成app
2018-10-05 23:02 1440install4j有windows版也有mac版 mac电脑 ... -
JavaFX Alert对话框
2018-10-05 22:01 23811. 标准对话框 消息对话框 Alert alert = ... -
IDEA Properties中文unicode转码问题
2017-02-17 19:54 1051摘要: 如何让IDEA的properties中的中文进行uni ... -
spring 3中新增的@value注解
2016-11-01 09:32 643在spring 3.0中,可以通过使用@value,对一些如x ...
相关推荐
赠送jar包:transport-netty4-client-5.5.1.jar; 赠送原API文档:transport-netty4-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty4-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:transport-netty4-client-6.3.0.jar; 赠送原API文档:transport-netty4-client-6.3.0-javadoc.jar; 赠送源代码:transport-netty4-client-6.3.0-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:transport-netty4-client-5.5.1.jar; 赠送原API文档:transport-netty4-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty4-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
netty-socketio-netty-socketio-2.0.6 ,Socket.IO 是一个库,可以在客户端和服务器之间实现低延迟, 双向和基于事件的通信:netty-socketio-netty-socketio-2.0.6.tar.gznetty-socketio-netty-socketio-2.0.6.zip
赠送jar包:netty-transport-rxtx-4.1.74.Final.jar; 赠送原API文档:netty-transport-rxtx-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-rxtx-4.1.74.Final-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:transport-netty3-client-5.5.1.jar; 赠送原API文档:transport-netty3-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty3-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:transport-netty3-client-5.5.1.jar; 赠送原API文档:transport-netty3-client-5.5.1-javadoc.jar; 赠送源代码:transport-netty3-client-5.5.1-sources.jar; 赠送Maven依赖信息文件:transport-netty...
赠送jar包:netty-tcnative-classes-2.0.46.Final.jar; 赠送原API文档:netty-tcnative-classes-2.0.46.Final-javadoc.jar; 赠送源代码:netty-tcnative-classes-2.0.46.Final-sources.jar; 赠送Maven依赖信息...
赠送jar包:netty-transport-classes-epoll-4.1.73.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.73.Final-sources.jar;...
赠送jar包:netty-resolver-dns-4.1.65.Final.jar; 赠送原API文档:netty-resolver-dns-4.1.65.Final-javadoc.jar; 赠送源代码:netty-resolver-dns-4.1.65.Final-sources.jar; 赠送Maven依赖信息文件:netty-...
赠送jar包:netty-codec-mqtt-4.1.73.Final.jar; 赠送原API文档:netty-codec-mqtt-4.1.73.Final-javadoc.jar; 赠送源代码:netty-codec-mqtt-4.1.73.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-...
赠送jar包:reactor-netty-http-1.0.15.jar; 赠送原API文档:reactor-netty-http-1.0.15-javadoc.jar; 赠送源代码:reactor-netty-http-1.0.15-sources.jar; 赠送Maven依赖信息文件:reactor-netty-...
netty-buffer-4.1.32.Final-sources.jar netty-buffer-4.1.32.Final.jar netty-build-22-sources.jar netty-build-22.jar netty-codec-4.1.32.Final-sources.jar netty-codec-4.1.32.Final.jar netty-codec-...
赠送jar包:netty-transport-native-unix-common-4.1.73.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.73....
赠送jar包:netty-codec-dns-4.1.65.Final.jar; 赠送原API文档:netty-codec-dns-4.1.65.Final-javadoc.jar; 赠送源代码:netty-codec-dns-4.1.65.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-dns-...
赠送jar包:reactor-netty-core-1.0.15.jar; 赠送原API文档:reactor-netty-core-1.0.15-javadoc.jar; 赠送源代码:reactor-netty-core-1.0.15-sources.jar; 赠送Maven依赖信息文件:reactor-netty-core-1.0.15....
赠送jar包:reactor-netty-http-1.0.11.jar; 赠送原API文档:reactor-netty-http-1.0.11-javadoc.jar; 赠送源代码:reactor-netty-http-1.0.11-sources.jar; 赠送Maven依赖信息文件:reactor-netty-...
赠送jar包:netty-codec-http2-4.1.74.Final.jar; 赠送原API文档:netty-codec-http2-4.1.74.Final-javadoc.jar; 赠送源代码:netty-codec-http2-4.1.74.Final-sources.jar; 赠送Maven依赖信息文件:netty-codec-...
赠送jar包:netty-transport-classes-epoll-4.1.74.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.74.Final-sources.jar;...
赠送jar包:netty-transport-native-unix-common-4.1.74.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.74....