Java CompletableFuture 链调用接口
Java CompletableFuture chain calls on interface
我有一些依赖接口的工作流抽象 WorkflowStep
:
public interface WorkflowStep {
public void executeStep();
}
现在我有三个不同的class实现这个接口的实体:
GetCoordinatesForWaypoints, DisplayDetails, PlaySounds
我的目标是将它们与 CompletableFuture
链接在一起,目前每个覆盖的 executeStep()
方法都在一个可运行的环境中运行,例如此处所示:
public class GetCoordinatesForEndpoints implements WorkflowStep {
@Override
public void executeStep() {
new Thread(new Runnable() {
@Override
public void run() {
//download coordinates from open street map
}).start();
}
}
其他 classes 方法看起来很相似。现在我有一个中央 class 工作流程开始的地方。目前看起来像这样:
public class DetailsDispatchWorkflow implements DispatchWorkflow {
private List<WorkflowStep> workflowSteps;
public DetailsDispatchWorkflow() {
workflowSteps = new LinkedList<>();
}
@Override
public void start() {
workflowSteps.add(new GetCoordinatesForEndpoints());
workflowSteps.add(new DisplayDetails());
workflowSteps.add(new PlaySounds());
workflowSteps.forEach(WorkflowStep::executeStep);
}
}
现在我想用 CompletableFuture
s 替换它。我尝试的第一件事是做这样的事情:
ExecutorService executorService = Executors.newFixedThreadPool(5);
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture.supplyAsync(() -> new
GetCoordinatesForEndpoints().executeStep(), executorService);
这给了我一个错误(我认为是因为被调用的方法 return 无效)。仅调用构造函数有效。我的下一步是用 thenAccept
链接这些调用(因为被调用的操作没有 return 值),但是当我追加
时,这也不起作用
.thenAccept(() -> new DisplayDetails().executeStep(), executorService);
我收到编译器无法推断功能接口类型的错误。我的问题是:如何实现以下调用链:
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture
.supplyAsync(() -> new GetCoordinatesForEndpoints().executeStep(), executorService)
.thenAccept(() -> new DisplayDetails().executeStep(), executorService)
.thenAcceptAsync(() -> new PlaySounds().executeStep(), executorService);
当所有实例化对象实现相同的接口时?
你的WorkflowStep
接口基本上等同于Runnable
:没有输入,没有输出。在 CompletableFuture
API 中,你应该使用相应的 runAsync()
和 thenRunAsync()
方法:
CompletableFuture<Void> workflowStepCompletableFuture =
CompletableFuture
.runAsync(() -> new GetCoordinatesForEndpoints().executeStep(), executorService)
.thenRunAsync(() -> new DisplayDetails().executeStep(), executorService)
.thenRunAsync(() -> new PlaySounds().executeStep(), executorService);
这将使所有这些 运行 异步但按顺序进行(就像您正在尝试做的那样)。
当然,您还应该从您的实施中删除 Thread
创建以使其有用。
我有一些依赖接口的工作流抽象 WorkflowStep
:
public interface WorkflowStep {
public void executeStep();
}
现在我有三个不同的class实现这个接口的实体:
GetCoordinatesForWaypoints, DisplayDetails, PlaySounds
我的目标是将它们与 CompletableFuture
链接在一起,目前每个覆盖的 executeStep()
方法都在一个可运行的环境中运行,例如此处所示:
public class GetCoordinatesForEndpoints implements WorkflowStep {
@Override
public void executeStep() {
new Thread(new Runnable() {
@Override
public void run() {
//download coordinates from open street map
}).start();
}
}
其他 classes 方法看起来很相似。现在我有一个中央 class 工作流程开始的地方。目前看起来像这样:
public class DetailsDispatchWorkflow implements DispatchWorkflow {
private List<WorkflowStep> workflowSteps;
public DetailsDispatchWorkflow() {
workflowSteps = new LinkedList<>();
}
@Override
public void start() {
workflowSteps.add(new GetCoordinatesForEndpoints());
workflowSteps.add(new DisplayDetails());
workflowSteps.add(new PlaySounds());
workflowSteps.forEach(WorkflowStep::executeStep);
}
}
现在我想用 CompletableFuture
s 替换它。我尝试的第一件事是做这样的事情:
ExecutorService executorService = Executors.newFixedThreadPool(5);
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture.supplyAsync(() -> new
GetCoordinatesForEndpoints().executeStep(), executorService);
这给了我一个错误(我认为是因为被调用的方法 return 无效)。仅调用构造函数有效。我的下一步是用 thenAccept
链接这些调用(因为被调用的操作没有 return 值),但是当我追加
.thenAccept(() -> new DisplayDetails().executeStep(), executorService);
我收到编译器无法推断功能接口类型的错误。我的问题是:如何实现以下调用链:
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture
.supplyAsync(() -> new GetCoordinatesForEndpoints().executeStep(), executorService)
.thenAccept(() -> new DisplayDetails().executeStep(), executorService)
.thenAcceptAsync(() -> new PlaySounds().executeStep(), executorService);
当所有实例化对象实现相同的接口时?
你的WorkflowStep
接口基本上等同于Runnable
:没有输入,没有输出。在 CompletableFuture
API 中,你应该使用相应的 runAsync()
和 thenRunAsync()
方法:
CompletableFuture<Void> workflowStepCompletableFuture =
CompletableFuture
.runAsync(() -> new GetCoordinatesForEndpoints().executeStep(), executorService)
.thenRunAsync(() -> new DisplayDetails().executeStep(), executorService)
.thenRunAsync(() -> new PlaySounds().executeStep(), executorService);
这将使所有这些 运行 异步但按顺序进行(就像您正在尝试做的那样)。
当然,您还应该从您的实施中删除 Thread
创建以使其有用。