可以传递给 ExecutorService 的对象,并且在 Runnables 之间具有依赖关系
An object that can be passed to ExecutorService, and has a dependency between Runnables
我正在尝试创建一个具有依赖关系的对象。关键是,具有 ExecutorService 的 class 和生成 Runnables 的 class 是不同的。这是简单的抽象:
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?
}
}
当这些 class 是一个时,我曾经使用 CompletableFuture:
CompletableFuture.runAsync(r1, pool)
.thenRunAsync(r2, pool)
.exceptionally(ex -> { // Do something });
但现在 pool
居住在另一个 class。我看到了更多 CompletableFuture class 的文档,但我仍然不确定它是否有帮助。
这里有人知道吗?
有人可能会争辩说 Batch
class 应该提供一些必须按顺序处理的 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
,您的 class 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);
}
}
}
对于线性依赖关系,您可以 return 一个新的 Runnable
来逐一执行任务。这样您就可以完全控制执行顺序。 Runnable
的列表不能保证顺序 - 您还需要其他 class 来遵守合同。
public Runnable getRunnable() {
Runnable r1 = ...
Runnable r2 = ...
return ()->{
r1.run();
r2.run();
};
}
我实际上有一个支持 Runnable Depenency Graph 的想法,但不确定何时会有用。有时间我会试着码一下
我正在尝试创建一个具有依赖关系的对象。关键是,具有 ExecutorService 的 class 和生成 Runnables 的 class 是不同的。这是简单的抽象:
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?
}
}
当这些 class 是一个时,我曾经使用 CompletableFuture:
CompletableFuture.runAsync(r1, pool)
.thenRunAsync(r2, pool)
.exceptionally(ex -> { // Do something });
但现在 pool
居住在另一个 class。我看到了更多 CompletableFuture class 的文档,但我仍然不确定它是否有帮助。
这里有人知道吗?
有人可能会争辩说 Batch
class 应该提供一些必须按顺序处理的 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
,您的 class 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);
}
}
}
对于线性依赖关系,您可以 return 一个新的 Runnable
来逐一执行任务。这样您就可以完全控制执行顺序。 Runnable
的列表不能保证顺序 - 您还需要其他 class 来遵守合同。
public Runnable getRunnable() {
Runnable r1 = ...
Runnable r2 = ...
return ()->{
r1.run();
r2.run();
};
}
我实际上有一个支持 Runnable Depenency Graph 的想法,但不确定何时会有用。有时间我会试着码一下