netty创建并启动新线程流程分析

本文主要分享服务端ServerSocketChannel所绑定的NioEventLoop的线程的创建过程

在服务端启动流程中当执行到注册操作时,会判断当前线程是否是ServerSocketChannel所绑定的NioEventLoop中的线程,如果不是的话,会将注册操作封装成一个线程任务交给NioEventLoop中的线程去执行,相关代码如下所示:

@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    if (eventLoop == null) {
        throw new NullPointerException("eventLoop");
    }
    if (isRegistered()) {
        promise.setFailure(new IllegalStateException("registered to an event loop already"));
        return;
    }
    if (!isCompatible(eventLoop)) {
        promise.setFailure(
                new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
        return;
    }

    AbstractChannel.this.eventLoop = eventLoop;

    if (eventLoop.inEventLoop()) {
        register0(promise);
    } else {//如果当前线程不是ServerSocketChannel所绑定的NioEventLoop中的线程
        try {
            eventLoop.execute(new Runnable() {
                @Override
                public void run() {
                    register0(promise);
                }
            });
        } catch (Throwable t) {
            logger.warn(
                    "Force-closing a channel whose registration task was not accepted by an event loop: {}",
                    AbstractChannel.this, t);
            closeForcibly();
            closeFuture.setClosed();
            safeSetFailure(promise, t);
        }
    }
}

代码中会调用eventLoop.inEventLoop()方法判断当前线程是否是eventLoop中的线程,如果不是的话,会调用eventLoop.execute(Runnable runnable)方法将任务提交给eventLoop执行。

相关逻辑在父类SingleThreadEventxecutor类中实现:

/**
* 在执行注册逻辑时,当前的线程是主线程
*/
@Override
public void execute(Runnable task) {
    if (task == null) {//合法性校验
        throw new NullPointerException("task");
    }
	//当前线程是否是ServerSocketChannel所绑定的线程EventLoop中的线程
    //当前线程是main线程,所以inEventLoop应为false
    boolean inEventLoop = inEventLoop(); 
    addTask(task);//将线程任务添加到EventLoop中的任务队列
    if (!inEventLoop) {
        startThread();//启动线程
        //如果线程已经关闭则移除上面提交到任务队列中的任务,并调用拒绝策略,拒绝任务的执行
        if (isShutdown() && removeTask(task)) {
            reject();
        }
    }

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

将线程任务添加到线程的任务队列中

protected void addTask(Runnable task) {
    if (task == null) {
        throw new NullPointerException("task");
    }
    if (!offerTask(task)) {
        reject(task);
    }
}

创建并启动线程

线程的状态枚举

key value 含义
ST_NOT_STARTED 1 线程尚未启动
ST_STARTED 2 线程已启动
ST_SHUTTING_DOWN 3 线程正在关闭
ST_SHUTDOWN 4 线程已经关闭
ST_TERMINATED 5 线程已终止
//如果线程尚未启动,则调用Unsafe修改线程的对应属性
//调用doStartThread()方法启动线程
private void startThread() {
    if (state == ST_NOT_STARTED) {
        if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {
            try {
                doStartThread();
            } catch (Throwable cause) {
                STATE_UPDATER.set(this, ST_NOT_STARTED);
                PlatformDependent.throwException(cause);
            }
        }
    }
}
private void doStartThread() {
    assert thread == null;//断言当前线程为空
    //调用ThreadPerTaskExecutor的execute(Runnable task)方法执行创建线程任务
    executor.execute(new Runnable() {
        @Override
        public void run() {
            thread = Thread.currentThread();
            if (interrupted) {
                thread.interrupt();
            }

            boolean success = false;
            updateLastExecutionTime();//记录执行时间
            try {
                SingleThreadEventExecutor.this.run();
                success = true;
            } catch (Throwable t) {
                logger.warn("Unexpected exception from an event executor: ", t);
            } finally {
                for (;;) {
                    int oldState = state;
                    if (oldState >= ST_SHUTTING_DOWN || STATE_UPDATER.compareAndSet(
                            SingleThreadEventExecutor.this, oldState, ST_SHUTTING_DOWN)) {
                        break;
                    }
                }

                // Check if confirmShutdown() was called at the end of the loop.
                if (success && gracefulShutdownStartTime == 0) {
                    if (logger.isErrorEnabled()) {
                        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 {
                        STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED);
                        threadLock.release();
                        if (!taskQueue.isEmpty()) {
                            if (logger.isWarnEnabled()) {
                                logger.warn("An event executor terminated with " +
                                        "non-empty task queue (" + taskQueue.size() + ')');
                            }
                        }

                        terminationFuture.setSuccess(null);
                    }
                }
            }
        }
    });
}

ThreadPerTaskExecutor

ThreadPerTaskExecutor类如下所示

public final class ThreadPerTaskExecutor implements Executor {
    private final ThreadFactory threadFactory;

    public ThreadPerTaskExecutor(ThreadFactory threadFactory) {
        if (threadFactory == null) {
            throw new NullPointerException("threadFactory");
        }
        this.threadFactory = threadFactory;
    }

    @Override
    public void execute(Runnable command) {
        threadFactory.newThread(command).start();//调用线程工程的NewThread方法创建线程并启动
    }
}

DefaultThreadFactory线程工厂的newThread方法的代码如下所示,即通过DefaultThreadFactory线程工厂创建的线程是FastThreadLocalThread类,该类为Netty对JDK原生的Thread类的扩展,后续文章详细分析该类,这里可以暂时将其视为Thread。

@Override
public Thread newThread(Runnable r) {
    Thread t = newThread(FastThreadLocalRunnable.wrap(r), prefix + nextId.incrementAndGet());
    try {
        if (t.isDaemon() != daemon) {//设置线程是否是守护线程
            t.setDaemon(daemon);
        }

        if (t.getPriority() != priority) {//设置线程的优先级
            t.setPriority(priority);
        }
    } catch (Exception ignored) {
    }
    return t;
}

protected Thread newThread(Runnable r, String name) {
    return new FastThreadLocalThread(threadGroup, r, name);
}

NioEventLoop、SingleThreadEventExecutor和ThreadPerTaskExecutor三者的关系

NioEventLoop、SingleThreadEventExecutor和ThreadPerTaskExecutor三者的关系如下所示:

SingleThreadEventExecutor类的主要作用是执行线程任务

ThreadPerTaskExecutor类的主要作用是创建Netty线程

SingleThreadEventExecutor类是NioEventLoop的父类,ThreadPerTaskExecutor是SingleThreadEventExecutor的一个成员属性,通过构造函数初始化。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HAQfCnKv-1579501393050)(/Users/lijiaxing/Desktop/要看的书/文章图片/NioEventLoop、SingleThreadEventExecutor和ThreadPerTaskExecutor的关系.png)]

eventLoop.execute(Runnable task) —>

SingleThreadEventExecutor.execute(Runnable task)—>

startThread()—>

doStartThread();—>

executor.execute(Runnable task)—>

ThreadPerTaskExecutor.execute(Runnable command)—》

DefaultThreadFactory.newThread(Runnable r)

总结

1、在EventLoop执行线程任务的时候创建线程,故Netty的EventLoop中的线程是Lazy create的

2、创建EventLoop线程的调用链为

eventLoop.execute(Runnable task)

​ —>SingleThreadEventExecutor.execute(Runnable task)

​ —>startThread()

​ —>doStartThread()

​ —>executor.execute(Runnable task)

​ —>ThreadPerTaskExecutor.execute(Runnable command)

​ —>DefaultThreadFactory.newThread(Runnable r)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章