NioEventLoop
来源:互联网 发布:当前网络受限 编辑:程序博客网 时间:2024/06/10 00:01
上一篇文章提到了NioEventLoopGroup,那么这篇文章就要提到NioEventLoop了,可以简单的理解为一个NioEventLoopGroup中有很多NioEventLoop真正的执行工作。
首先我们还是来看一下NioEventLoop的继承体系:
其实相对还是比较直线型的集成体系。。
首先在AbstractEventExecutor中定义了一些基本的executor的方法,例如submit任务,调度任务等。
接着,在SingleThreadEventExecutor中则进行了一些详细的定义,我们来看看它的构造函数,基本上就明白了:
//构造函数 protected SingleThreadEventExecutor( EventExecutorGroup parent, ThreadFactory threadFactory, boolean addTaskWakesUp) { if (threadFactory == null) { throw new NullPointerException("threadFactory"); } this.parent = parent; this.addTaskWakesUp = addTaskWakesUp; thread = threadFactory.newThread(new Runnable() { //创建线程 @Override //线程的执行函数 public void run() { CURRENT_EVENT_LOOP.set(SingleThreadEventExecutor.this); boolean success = false; updateLastExecutionTime(); try { SingleThreadEventExecutor.this.run(); //开始当前executor的执行函数 success = true; } catch (Throwable t) { logger.warn("Unexpected exception from an event executor: ", t); } finally { if (state < ST_SHUTTING_DOWN) { state = ST_SHUTTING_DOWN; } // Check if confirmShutdown() was called at the end of the loop. if (success && gracefulShutdownStartTime == 0) { logger.error( "Buggy " + EventExecutor.class.getSimpleName() + " implementation; " + SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called " + "before run() implementation terminates."); } try { // Run all remaining tasks and shutdown hooks. for (;;) { if (confirmShutdown()) { break; } } } finally { try { cleanup(); } finally { synchronized (stateLock) { state = ST_TERMINATED; } threadLock.release(); if (!taskQueue.isEmpty()) { logger.warn( "An event executor terminated with " + "non-empty task queue (" + taskQueue.size() + ')'); } } } } } }); taskQueue = newTaskQueue(); //构造任务队列 }在构造函数中定义了执行线程,并且还构造了任务队列,用于保存当前executor需要执行的所有任务。
接下来就是SingleThreadEventLoop,它继承自SingleThreadEventExecutor,这其实和group里面的差不多,我们最终用的是eventloop,但是eventloop本身也是一个eventexecutor。
在SingleThreadEventLoop中,定一些一些eventloop的基本方法,例如register方法。
最后就是NioEventLoop了,在它里面实现了各种事件循环的方法,其实最重要的还是run方法,这也是在singlethreadexecutor中线程要执行的方法,我们来看看它的定义吧:
protected void run() { for (;;) { oldWakenUp = wakenUp.getAndSet(false); try { if (hasTasks()) { selectNow(); } else { select(); // 'wakenUp.compareAndSet(false, true)' is always evaluated // before calling 'selector.wakeup()' to reduce the wake-up // overhead. (Selector.wakeup() is an expensive operation.) // // However, there is a race condition in this approach. // The race condition is triggered when 'wakenUp' is set to // true too early. // // 'wakenUp' is set to true too early if: // 1) Selector is waken up between 'wakenUp.set(false)' and // 'selector.select(...)'. (BAD) // 2) Selector is waken up between 'selector.select(...)' and // 'if (wakenUp.get()) { ... }'. (OK) // // In the first case, 'wakenUp' is set to true and the // following 'selector.select(...)' will wake up immediately. // Until 'wakenUp' is set to false again in the next round, // 'wakenUp.compareAndSet(false, true)' will fail, and therefore // any attempt to wake up the Selector will fail, too, causing // the following 'selector.select(...)' call to block // unnecessarily. // // To fix this problem, we wake up the selector again if wakenUp // is true immediately after selector.select(...). // It is inefficient in that it wakes up the selector for both // the first case (BAD - wake-up required) and the second case // (OK - no wake-up required). if (wakenUp.get()) { selector.wakeup(); } } cancelledKeys = 0; final long ioStartTime = System.nanoTime(); processSelectedKeys(); //处理所有选出来的key final long ioTime = System.nanoTime() - ioStartTime; final int ioRatio = this.ioRatio; runAllTasks(ioTime * (100 - ioRatio) / ioRatio); //执行所有的任务 if (isShuttingDown()) { closeAll(); if (confirmShutdown()) { break; } } } catch (Throwable t) { logger.warn("Unexpected exception in the selector loop.", t); // Prevent possible consecutive immediate failures that lead to // excessive CPU consumption. try { Thread.sleep(1000); } catch (InterruptedException e) { // Ignore. } } } }
就这样,NioEventLoop和NioEventLoopGroup两条主线就差不多了,可以有以下总结,
EventLoop里面会包含EventExecutor,也就是说事件循环同时也是一个事件的执行器,group可以把它看做是一个容器。。。。
接下来可以分析Netty里面channel的定义了。。。。。
- NioEventLoop
- NioEventLoop源码
- 【Netty源码解析】NioEventLoop
- NioEventLoop源码分析
- netty5.0之SingleThreadEventLoop & NioEventLoop
- Netty4学习笔记-- NioEventLoopGroup NioEventLoop
- 【Netty源码】NioEventLoop源码剖析
- netty4源码分析——NioEventLoop
- Netty之Reactor线程2 -- NioEventLoop
- Netty4学习笔记(6)-- NioEventLoop继承层次结构
- Netty4源码分析-NioEventLoop实现的线程运行逻辑
- Netty4学习笔记(6)-- NioEventLoop继承层次结构
- 【Netty4.X】Netty源码分析之NioEventLoop(六)
- Netty源码分析:NioEventLoop启动以及其IO操作和Task任务的处理
- mssql 对文件夹里面文件进行重命名,前面加上时间戳
- php email验证
- 计算机科学中最重要的32个算法
- 关于NS-2仿真中移动节点的设置 [转载]
- GDB调试基本流程
- NioEventLoop
- apt-get 使用详解
- Java Web系统架构设计需要解决的几个问题
- 黑马程序员_毕向东JAVA基础_面向对象(封装&继承&多态)
- asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
- javaWeb 编码问题
- Cache与Buffer的区别
- 关于https://urs.microsoft.com/urs.asmx .
- openfire二次开发:使用Annotation注解VO转换xml文档