本文主要分享服务端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类如下所示
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三者的关系如下所示:
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)