其中executor
方法对应的是SingleThreadEventExecutor
的execute
方法
private void execute(Runnable task, boolean immediate) { boolean inEventLoop = inEventLoop(); addTask(task); if (!inEventLoop) { startThread(); if (isShutdown()) { ...... } } if (!addTaskWakesUp && immediate) { ...... } }inEventLoop()
经过上述分析 , 为false
,所以执行startThread()
方法
private void startThread() { if (state == ST_NOT_STARTED) { if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) { boolean success = false; try { doStartThread(); success = true; } finally { if (!success) { STATE_UPDATER.compareAndSet(this, ST_STARTED, ST_NOT_STARTED); } } } } }这里主要的逻辑就是判断线程是否启动 , 如果没有启动,就调用doStartThread()
启动 。doStartThread()
的逻辑是
private void doStartThread() { assert thread == null; executor.execute(new Runnable() { @Override public void run() { thread = Thread.currentThread(); ... SingleThreadEventExecutor.this.run(); ...... } }); }通过一个成员变量thread
来保存ThreadPerTaskExecutor
创建出来的线程(即:FastThreadLocalThread) , NioEventLoop 保存完线程的引用之后,随即调用 run 方法 。
workGroup 对应的 NioEventLoop 创建线程和启动workGroup 对应的 NioEventLoop 创建的线程主要做如下事情
- 执行一次事件轮询 。首先轮询注册到 Reactor 线程对应的 Selector 上的所有 Channel 的 IO 事件 。
- 处理产生 IO 事件的 Channel 。如果有读写或者新连接接入事件,则处理:
- 处理任务队列 。
事件轮询事件轮询调用了
NioEventLoop
的如下方法private int select(long deadlineNanos) throws IOException { if (deadlineNanos == NONE) { return selector.select(); } // Timeout will only be 0 if deadline is within 5 microsecs long timeoutMillis = deadlineToDelayNanos(deadlineNanos + 995000L) / 1000000L; return timeoutMillis <= 0 ? selector.selectNow() : selector.select(timeoutMillis); }
推荐阅读
- ZCTF note3:一种新解法
- 学习ASP.NET Core Blazor编程系列四——迁移
- 五 Netty 学习:服务端启动核心流程源码说明
- 【前端必会】走进webpack生命周期,另类的学习方法
- opencvcv.line
- 骰子五个点怎么玩(骰子五个六五个七怎么玩)
- 三十六 Java开发学习----SpringBoot三种配置文件解析
- 4 MySQL学习---MySQL索引
- 基础&进阶 线段树学习笔记(一) | P3372 【模板】线段树 1 题解
- 王者荣耀七周年击败特效怎么领取