接口 ICompletionStage<T>

所有已知子接口:
IFuture<T>, IPromise<T>, IScheduledFuture<V>, IScheduledPromise<V>
所有已知实现类:
ForwardFuture, Promise, ReadOnlyFuture, ScheduledPromise, UniPromise, UniScheduledPromise

@ThreadSafe public interface ICompletionStage<T>

线程控制

虽然我在Stage上约定了记录Executor的方法,但是:Future上的监听器默认由【使Future进入完成状态的线程】通知!!! 因此Stage下游的【同步任务】的执行线程是不确定的!这可能导致线程安全问题、

如果期望控制下游任务的执行线程,请调用Async命名结尾的方法添加任务,并指定Executor; 如果觉得总是通过提交任务保证线程有额外的开销,或者可能导致时序问题,可使用TaskOption.STAGE_TRY_INLINE选项, Future在通知时,会判断是否已在目标线程,如果已在目标线程则同步执行,否则提交任务异步执行。

注意: 1. Async方法只保证给定的Action在目标线程执行,而不能保证其后续操作所在的线程。
2. 如果用于执行任务的Executor已关闭,则切换线程会失败,任务会以RejectedExecutionException失败

小心Compose

Compose操作,最容易犯的错误是:认为ComposeAsync的下游任务在给定的Executor中执行。 Compose操作,不论是否是Async方法,都不能直接保证下游任务的执行线程;Compose操作的下游任务总是由使返回的Future进入完成状态的线程通知; 因此,要保证下游任务的运行线程,必须再添加一个Stage来保证。

      // 错误的方式
      future.composeApplyAsync(executor, (ctx, v) -> {
          // 在参数指定的executor线程
          // inExecutor(executor) == true;
      }), ctx, 0)
      .thenApply((ctx, v) -> {
          // 在使Future进入完成状态的线程
          // inExecutor(executor) == ?
      })

      // 正确的方式
      future.composeApplyAsync(executor, (ctx, v) -> {
          // 在参数指定的executor线程
          // inExecutor(executor) == true;
      }), ctx, 0)
      .thenApplyAsync(executor, (ctx, v) -> {
          // 在参数指定的executor线程
          // inExecutor(executor) == true;
      },  ctx, TaskOption.STAGE_TRY_INLINE)
 

行为取消

Stage并不直接提供删除Action的方法,要取消行为,请通过IContext.cancelToken()发起取消命令。 Stage会在执行用户的Action之前检查取消信号,另外用户的Action在运行的过程中也可主动检测取消信号。

其它

1.关于Future之间的聚合,见:FutureCombiner 2.java参数不支持默认值,为减少方法数,我们只提供一种重载。 3.大家可以先熟悉JDK的CompletionStageCompletableFuture
作者:
wjybxx date - 2024/1/10