20220529_netty中SingleThreadEventExecutor线程创建过程分析学习笔记
1概述
SingleThreadEventExecutor线程本质就是原生ThreadPoolExecutor线程的创建。
可借助章节2测试代码进行源码走读,本节主要有一下几点:
- ThreadPoolExecutor线程的创建、任务的提交
- SingleThreadEventExecutor线程的创建、任务的提交
1.1ThreadPoolExecutor线程的创建、任务的提交
1.1.1ThreadPoolExecutor内置threadFactory
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
1.1.2newThread创建线程的方法
static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory() {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() :
Thread.currentThread().getThreadGroup();
// 线程名称:pool-1-thread-1
namePrefix = "pool-" +
poolNumber.getAndIncrement() +
"-thread-";
}
// 创建线程
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r,
namePrefix + threadNumber.getAndIncrement(),
0);
if (t.isDaemon())
t.setDaemon(false);
if (t.getPriority() != Thread.NORM_PRIORITY)
t.setPriority(Thread.NORM_PRIORITY);
return t;
}
}
1.1.3真正Jdk线程创建的地方
// C:\Program Files\Java\jdk1.8.0_60\src.zip!\java\util\concurrent\ThreadPoolExecutor.java
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (addWorker(command, true))
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask); // 开始创建线程
/**
* Creates with given first task and thread from ThreadFactory.
* @param firstTask the first task (null if none)
*/
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this); // 调用1.2.2中的方法
}
1.2SingleThreadEventExecutor线程的创建、任务的提交
// 确保线程值启动一次,并发安全性
private static final AtomicIntegerFieldUpdater STATE_UPDATER =
AtomicIntegerFieldUpdater.newUpdater(SingleThreadEventExecutor.class, "state");
1.2.1SingleThreadEventExecutor抽象类关系图
SingleThreadEventExecutor抽象类:延时任务,获取待执行和过期任务,并执行,内置Queue
taskQueue。 -
SingleThreadEventLoop抽象类:实现EventLoopGroup接口中的next,注册等方法,内置额外的时间循环任务队列,tailTasks queue
,作为参数给SingleThreadEventExecutor.runAllTasksFrom调用,问题来了,taskQueue不够吗? protected final boolean runAllTasksFrom(Queue
taskQueue) {。
- DefaultEventLoop:无限循环,实现从队列中取任务,执行任务等一些列的。
// E:\workdirectory\Dev\study\netty-4.1\transport\src\main\java\io\netty\channel\DefaultEventLoop.java
// 实现了SingleThreadEventExecutor抽象类的run方法。
@Override
protected void run() {
for (;;) {
// 1.调用SingleThreadEventExecutor.takeTask获取任务。
Runnable task = takeTask();
if (task != null) {
task.run();
// 3.调用SingleThreadEventExecutor.updateLastExecutionTime
updateLastExecutionTime();
}
// 3.调用SingleThreadEventExecutor.confirmShutdown
if (confirmShutdown()) {
break;
}
}
}
1.2.2线程的创建逻辑
1.2.2.1构建SingleThreadEventExecutor执行器
@Test
public void testWrappedExecutorIsShutdown() {
// 1.设定一个线程
ExecutorService executorService = Executors.newSingleThreadExecutor();
final SingleThreadEventExecutor executor =
new SingleThreadEventExecutor(null, executorService, false) {
1.2.2.1包装原生Jdkexecutor
protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,
// 线程执行器的包装类:ThreadExecutorMap
// 参数1 executor:ThreadPerTaskExecutor
// 参数2 this:SingleThreadEventExecutor
this.executorWrap = ThreadExecutorMap.apply(executor, this);
this.executor = ThreadExecutorMap.apply(executor, this);
// E:\workdirectory\Dev\study\netty-4.1\common\src\main\java\io\netty\util\internal\ThreadExecutorMap.java
return new Executor() {
@Override
public void execute(final Runnable command) {
// step1:对原始 executor进行包装
// 后面外界的入口execute-->apply、execute
// 注意 threadPoolExecutor:java.util.concurrent.ThreadPoolExecutor
// 提交任务的时候,会在这里创建线程,并执行这个runnable方法,runnable内部是一个取任务的无线循环
// 但一直在这个工作线程中执行 while (!confirmShutdown()) {
executor.execute(apply(command, eventExecutor));
}
};
// E:\workdirectory\Dev\study\netty-4.1\common\src\main\java\io\netty\util\internal\ThreadExecutorMap.java
// apply逻辑分析,设置当前的事件执行器,返回业务runnable,并真正的线程池提交执行
public static Runnable apply(final Runnable command, final EventExecutor eventExecutor) {
ObjectUtil.checkNotNull(command, "command");
ObjectUtil.checkNotNull(eventExecutor, "eventExecutor");
return new Runnable() {
@Override
public void run() {
setCurrentEventExecutor(eventExecutor);
try {
// step2:调用 doStartThread中的execute runnable,循环取任务执行
// command 实际为:@@@@@@那方法
command.run();
} finally {
setCurrentEventExecutor(null);
}
}
};
}
1.2.2.2任务提交(首次进行线程创建)
// E:\workdirectory\Dev\study\netty-4.1\common\src\main\java\io\netty\util\concurrent\SingleThreadEventExecutor.java
private void execute(Runnable task, boolean immediate) { // immediate:true
boolean inEventLoop = inEventLoop();
addTask(task); // 业务的runnable方法
private void execute(Runnable task, boolean immediate) {
boolean inEventLoop = inEventLoop();
addTask(task);
if (!inEventLoop) {
startThread();
private void doStartThread() {
assert thread == null;
executor.execute(new Runnable() { // 人工构建一个runnable任务,循环调用takeTask方法
// E:\workdirectory\Dev\study\netty-4.1\common\src\main\java\io\netty\util\concurrent\SingleThreadEventExecutor.java
private void doStartThread() {
assert thread == null;
// 执行 2.1.3中的方法
executor.execute(
***********************************************************************
new Runnable() {
@Override
public void run() { // 这个方法实际一直不会结束的@@@@@@
thread = Thread.currentThread();
if (interrupted) {
thread.interrupt();
}
boolean success = false;
updateLastExecutionTime();
try {
// 去队列里取任务执行
// 执行模板方法,实现类里的 SingleThreadEventLoopTest.java,for (;;) {
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. At this point the event loop
// is in ST_SHUTTING_DOWN state still accepting tasks which is needed for
// graceful shutdown with quietPeriod.
for (;;) {
if (confirmShutdown()) {
break;
}
}
// Now we want to make sure no more tasks can be added from this point. This is
// achieved by switching the state. Any new tasks beyond this point will be rejected.
for (;;) {
int oldState = state;
if (oldState >= ST_SHUTDOWN || STATE_UPDATER.compareAndSet(
SingleThreadEventExecutor.this, oldState, ST_SHUTDOWN)) {
break;
}
}
// We have the final set of tasks in the queue now, no more can be added, run all remaining.
// No need to loop here, this is the final pass.
confirmShutdown();
} finally {
try {
cleanup();
} finally {
// Lets remove all FastThreadLocals for the Thread as we are about to terminate and notify
// the future. The user may block on the future and once it unblocks the JVM may terminate
// and start unloading classes.
// See https://github.com/netty/netty/issues/6596.
FastThreadLocal.removeAll();
STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED);
threadLock.countDown();
int numUserTasks = drainTasks();
if (numUserTasks > 0 && logger.isWarnEnabled()) {
logger.warn("An event executor terminated with " +
"non-empty task queue (" + numUserTasks + ')');
}
terminationFuture.setSuccess(null);
}
}
}
}
}
***********************************************************************
);
}
2测试代码
@Test
public void testWrappedExecutorIsShutdown() throws InterruptedException {
// 1.构建ExecutorService
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 2.构建SingleThreadEventExecutor
final SingleThreadEventExecutor executor =
new SingleThreadEventExecutor(null, executorService, false) {
@Override
protected void run() {
while (!confirmShutdown()) {
Runnable task = takeTask();
if (task != null) {
task.run();
}
}
}
};
// 3.任务提交
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("do it");
// Noop.
}
});
TimeUnit.SECONDS.sleep(100);
executorService.shutdownNow();
assertTrue(executor.isShutdown());