我试图创建一个有依赖项的对象。重点是,一个有ExecutorService的类和一个生成Runnables的类是不同的。以下是简单的抽象:
public class Main {
private ExecutorService pool; // Initialized before executing main
public static void main(String[] args) {
List<Batch> batches = // fetching...
for(Batch batch : batches) {
Runnable r = batch.getRunnable();
pool.submit(r);
}
}
}
public class Batch {
public Runnable getRunnable() {
Runnable r1 = // creating...
Runnable r2 = // creating...
// FIXME: demand that r2 run after r1 finishes
return // something suitable. r1? r2? or new Runnable?
}
}
当这些类是一体的时候,我曾经使用CompletableFuture:
CompletableFuture.runAsync(r1, pool)
.thenRunAsync(r2, pool)
.exceptionally(ex -> { // Do something });
但是现在pool
驻留在另一个类中。我看到CompletableFuture类的文档越来越多,但我仍然不确定它是否有帮助。
这里有人知道吗?
对于线性依赖关系,只需返回一个新的Runnable
即可逐个执行任务。通过这种方式,您可以完全控制执行顺序。Runnable
的列表并不能保证订单——你还需要其他类来遵守合同。
public Runnable getRunnable() {
Runnable r1 = ...
Runnable r2 = ...
return ()->{
r1.run();
r2.run();
};
}
事实上,我有一个支持可运行Depenency图的想法,不确定什么时候会有用。我会在有时间后尝试对它进行编码。
有人可能会说,Batch
类应该提供许多必须按顺序处理的Runnable
。因此,将多个Runnable
封装在另一个Runnable
中可能会隐藏太多。
但我确实理解您将代码简化为Runnable
的要求。一个简单的解决方案可能是:
public class Batch implements Runnable{
public List<Runnable> getRunnable() {
Runnable r1 = // creating...
Runnable r2 = // creating...
// FIXME: demand that r2 run after r1 finishes
return // List of r1, r2, ....
}
@Override
public void run(){
for (Runnable r:getRunnable()){
r.run();
}
}
当然,通过这种方式,您的批次将被处理为一个Runnable
,而不是一系列Runnable
。
编辑
一旦Batch
实现了Runnable
,您的类Main
可能如下所示:
public class Main {
private ExecutorService pool; // Initialized before executing main
public static void main(String[] args) {
List<Batch> batches = // fetching...
for(Batch batch : batches) {
pool.submit(batch);
}
}
}