final IndexedInputGate[] gates = shuffleEnvironment.createInputGates(…);
 // 初始化一个用来执行 Task 的线程,目标对象,就是 Task 自己
 executingThread = new Thread(TASK_THREADS_GROUP, this, taskNameWithSubtask);
 }
## Task 线程启动


Task 的启动,是通过启动 Task 对象的内部 executingThread 来执行 Task 的,具体逻辑在 run 方法中:
private void doRun() {
 // 1、先更改 Task 的状态: CREATED ==> DEPLOYING
 transitionState(ExecutionState.CREATED, ExecutionState.DEPLOYING);
 // 2、准备 ExecutionConfig
 final ExecutionConfig executionConfig =
 serializedExecutionConfig.deserializeValue(userCodeClassLoader);
 // 3、初始化输入和输出组件, 拉起 ResultPartition 和 InputGate
 setupPartitionsAndGates(consumableNotifyingPartitionWriters,
 inputGates);
 // 4、注册 输出
 for(ResultPartitionWriter partitionWriter :
 consumableNotifyingPartitionWriters) {
 taskEventDispatcher.registerPartition(partitionWriter.getPartitionId());
 } /
 / 5、初始 环境对象 RuntimeEnvironment, 包装在 Task 执行过程中需要的各种组件
 Environment env = new RuntimeEnvironment(jobId, vertexId, executionId,
 …);
 // 6、初始化 调用对象
 // 两种最常见的类型: SourceStreamTask、OneInputStreamTask、
 TwoInputStreamTask
 // 父类: StreamTask
 // 通过反射实例化 StreamTask 实例(可能的两种情况: SourceStreamTask,
 OneInputStreamTask)
 AbstractInvokable invokable =
 loadAndInstantiateInvokable(userCodeClassLoader, nameOfInvokableClass, env);
 // 7、先更改 Task 的状态: DEPLOYING ==> RUNNING
 transitionState(ExecutionState.DEPLOYING, ExecutionState.RUNNING);
 // 8、真正把 Task 启动起来了
 invokable.invoke();
 // 9、StreamTask 需要正常结束,处理 buffer 中的数据
 for(ResultPartitionWriter partitionWriter :
 consumableNotifyingPartitionWriters) {
 if(partitionWriter != null) {
 partitionWriter.finish();
 }
 } /
 / 10、先更改 Task 的状态: RUNNING ==> FINISHED
 transitionState(ExecutionState.RUNNING, ExecutionState.FINISHED);
## StreamTask 初始化


StreamTask 初始化指的就是 SourceStreamTask 和 OneInputStreamTask 的实例对象的构建!Task 这个类,只是一个笼统意义上的 Task,就是一个通用 Task 的抽象,不管是批处理的,还是流式处理的,不管是 源Task, 还是逻辑处理 Task, 都被抽象成 Task 来进行调度执行!
private SourceStreamTask(Environment env, Object lock) throws Exception {
    super(
            env,
            null,
            FatalExitExceptionHandler.INSTANCE,
            StreamTaskActionExecutor.synchronizedExecutor(lock));
    this.lock = Preconditions.checkNotNull(lock);
    this.sourceThread = new LegacySourceFunctionThread();
    getEnvironment().getMetricGroup().getIOMetricGroup().setEnableBusyTime(false);
}

@Override
protected void init() {
    // we check if the source is actually inducing the checkpoints, rather
    // than the trigger
    SourceFunction<?> source = mainOperator.getUserFunction();
    if (source instanceof ExternallyInducedSource) {
        externallyInducedCheckpoints = true;

        ExternallyInducedSource.CheckpointTrigger triggerHook =
                new ExternallyInducedSource.CheckpointTrigger() {

                    @Override
                    public void triggerCheckpoint(long checkpointId) throws FlinkException {
                        // TODO - we need to see how to derive those. We should probably not
                        // encode this in the
                        // TODO - source's trigger message, but do a handshake in this task
                        // between the trigger
                        // TODO - message from the master, and the source's trigger
                        // notification
                        final CheckpointOptions checkpointOptions =
                                CheckpointOptions.forConfig(
                                        CheckpointType.CHECKPOINT,
                                        CheckpointStorageLocationReference.getDefault(),
                                        configuration.isExactlyOnceCheckpointMode(),
                                        configuration.isUnalignedCheckpointsEnabled(),
                                        configuration.getAlignedCheckpointTimeout().toMillis());
                        final long timestamp = System.currentTimeMillis();

                        final CheckpointMetaData checkpointMetaData =
                                new CheckpointMetaData(checkpointId, timestamp, timestamp);

                        try {
                            SourceStreamTask.super
                                    .triggerCheckpointAsync(
                                            checkpointMetaData, checkpointOptions)
                                    .get();
                        } catch (RuntimeException e) {
                            throw e;
                        } catch (Exception e) {
                            throw new FlinkException(e.getMessage(), e);
                        }
                    }
                };

        ((ExternallyInducedSource<?, ?>) source).setCheckpointTrigger(triggerHook);
    }
    getEnvironment()
            .getMetricGroup()
            .getIOMetricGroup()
            .gauge(
                    MetricNames.CHECKPOINT\_START\_DELAY\_TIME,
                    this::getAsyncCheckpointStartDelayNanos);
    recordWriter.setMaxOverdraftBuffersPerGate(0);
}
## StreamTask 执行


核心步骤如下:
public final void invoke() throws Exception {
 // Task 正式工作之前
 beforeInvoke();
 // Task 开始工作: 针对数据执行正儿八经的逻辑处理
 runMailboxLoop();
 // Task 要结束
 afterInvoke();
 // Task 最后执行清理
 cleanUpInvoke();
 }![img]()
![img]()
![img]()