我有一些依赖接口WorkflowStep
的工作流抽象:
public interface WorkflowStep {
public void executeStep();
}
现在,我有三个实现该接口的不同类:
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();
}
}
其他类方法看起来很相似。现在,我有一个开始工作流程的中心课程。当前看起来像这样:
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
代替它。我尝试做的第一件事是执行以下操作:
ExecutorService executorService = Executors.newFixedThreadPool(5);
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture.supplyAsync(() -> new
GetCoordinatesForEndpoints().executeStep(), executorService);
这给了我一个错误(我认为是因为被调用的方法返回void)。仅调用构造函数有效。我的下一步是将这些调用与thenAccept
链接起来(因为被调用的操作不会返回值),但是当我追加
.thenAccept(() -> new DisplayDetails().executeStep(), executorService);
我收到一个错误,指出编译器无法推断功能接口类型。我的问题是:如何实现以下呼叫链:
CompletableFuture<WorkflowStep> workflowStepCompletableFuture =
CompletableFuture
.supplyAsync(() -> new GetCoordinatesForEndpoints().executeStep(), executorService)
.thenAccept(() -> new DisplayDetails().executeStep(), executorService)
.thenAcceptAsync(() -> new PlaySounds().executeStep(), executorService);
何时所有实例化对象都实现相同的接口?
答案 0 :(得分:1)
您的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
创建的内容,以使其变得有用。