EventExecutor深入分析

531 阅读2分钟

在分析前,先写一段简单的Hello wordld代码来理解EventExecutor是如何工作

public static void main(String[] args) {
    EventExecutor eventExecutor = new DefaultEventExecutor();
    eventExecutor.submit(() -> {
        System.out.println("Hello world");
    });
}

这段代码非常的简单,就是提交一个事件给EventExecutor, 然后EventExecutor执行该事件,事件内容非常简单就是打印一下'Hello world'

DefaultEventExecutor 类继承结构

defaultEventExecutor.png

关键逻辑梳理

从上面代码看,仅调用了eventExecutor.submit(Runable comand)接口,那eventExecutor是如何执行上面的命令的呢,通过跟进到submit方法中,发现类 AbstractEventExecutor.submit 仅调用父类AbstractExecutorService.submit()方法, 该方法的实现非常简单,我就不贴源码了,感兴趣的同学自己看下 简单说下AbstractExecutorService.submit(Runnable task)方法的逻辑,非常简单 第一,创建一个RunnableFuture对象,然后调用Executor子类execute(Runnable task)方法

从上面的示例代码DefaultEventExecutor类看,在Executor的子类SingleThreadEventExecutor.execute(Runnable task)实现

public void execute(Runnable task) {
    if (task == null) {
        throw new NullPointerException("task");
    }

    //
    boolean inEventLoop = inEventLoop();
    if (inEventLoop) {
        addTask(task);
    } else {
        startThread();
        addTask(task);
        if (isShutdown() && removeTask(task)) {
            reject();
        }
    }

    if (!addTaskWakesUp && wakesUpForTask(task)) {
        wakeup(inEventLoop);
    }
}

该方法简单来讲如下

  1. 首先看当前执行的线程是否为本eventExecutor关联的线程,如果是,说明该eventExecutor正在执行其他任务,将新增加的任务添加到等待队列,结束
  2. 如果不是,如果该eventExecutor没有关联线程,则创建一个线程,创建线程完成后调用SingleThreadEventExecutor.this.run();执行关联的子任务,
  3. 如果任务队列为空,则将当前eventExecutor关联的线程推进到WAITING状态, 对应线程堆栈如下
"defaultEventExecutor-1-1" #13 prio=5 os_prio=31 tid=0x00007fb4c594c000 nid=0x5b03 waiting on condition [0x0000700002352000]
   java.lang.Thread.State: WAITING (parking)
	at sun.misc.Unsafe.park(Native Method)
	- parking to wait for  <0x000000076d3c7858> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
	at io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:238)
	at io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:64)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:887)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:745)

总结

eventExecutor是依赖单个线程去执行提交的event, 核心实现在SingleThreadEventExecutor类中,该类提供了模版方法execute(Runnable task)实现,提供抽象方法run()提供子类实现,该类会绑定固定的线程,执行子类的run()方法。