0

我正在尝试创建一个具有依赖关系的对象。关键是,具有 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 类的文档更多,但我仍然不确定它是否有帮助。

有没有人在这里有一些知识?

4

2 回答 2

1

有人可能会争辩说,一个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.

编辑

一旦Batchimplements 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);
    }
  }
}
于 2016-05-11T10:53:03.007 回答
1

对于线性依赖关系,您可以只返回一个新Runnable的,一个一个地执行任务。这样您就可以完全控制执行顺序。列表Runnable不能保证订单 - 您还需要其他类来尊重合同。

public Runnable getRunnable() {
    Runnable r1 = ...
    Runnable r2 = ...
    return ()->{
         r1.run();
         r2.run();
    };
}

我实际上有一个支持可运行依赖图的想法,但不确定什么时候会有用。我会在有时间后尝试对其进行编码。

于 2016-05-12T07:15:41.593 回答