自定义任务Executor或“我是重新发明轮子?”

时间:2014-06-16 11:55:35

标签: java multithreading concurrency java-8 java-stream

我正在尝试创建一个实用程序类,它将能够处理可运行的bundle并以不同的组合(sync,async)执行它们。

例如:假设这是一个复合任务的json表示。 “[]”保持异步任务,“{}”保持同步任务。

[
    task,
    [task, task, task],
    {task, task, [task, task]}
]

这是(将)以方法链方式实现:

fromAsyncTasks(
    from(runnable),
    fromSyncedTasks(from(runnable), from(runnable), from(runnable)),
    fromAsyncTasks(from(runnable), from(runnable), fromAsyncTasks(from(runnable), from(runnable)))
).execute();

正如您可能理解的那样.execute()以同步或异步方式递归调用其他任务execute()。此外,Task接口支持terminate()停止(中断任务),因此如果我保留对这些任务的引用,我将能够终止它们。

问题#1是:是否有任何工具,库至少提供此功能?

和#2:如果我使用流来执行paralel(异步情况),我该如何终止它们?

tasks.parallelStream().forEach(Runnable::run)

2 个答案:

答案 0 :(得分:4)

从Java 8开始,类java.util.concurrent.CompletableFuture是标准库的一部分。该课程基本上提供了构建所需内容所需的一切。

要直接支持您的用例,您需要某种抽象,即Runnable,任务的同步列表或异步任务列表。在以下代码中,此抽象是类Task

interface Task {
    CompletableFuture<Void> execute(
        CompletableFuture<Void> f, Executor e);
}

以下是三种工厂方法来创建三种不同类型的任务:

static Task wrap(Runnable runnable) {
    return (f, e) -> f.thenRunAsync(runnable, e);
}
static Task sync(Task... tasks) {
    return (f, e) -> {
        for (Task task : tasks) {
            f = task.execute(f, e);
        }
        return f;
    };
}
static Task async(Task... tasks) {
    return (f, e) -> tasks.length == 0 ? f :
        CompletableFuture.allOf(
        Arrays.stream(tasks)
        .map(t -> t.execute(f, e))
        .toArray(CompletableFuture[]::new));
}

现在,您可以轻松创建可运行,同步和异步任务的任意嵌套结构,并使用任意Executor执行它们。这是一个简短的例子:

public static void main(String... args) {
    Task task = sync(
        wrap(() -> log("1")),
        async(
            wrap(() -> log("A")),
            wrap(() -> log("B")),
            wrap(() -> log("C"))),
        wrap(() -> log("2")),
        wrap(() -> log("3")));
    ExecutorService executor = Executors.newFixedThreadPool(4);
    task.execute(CompletableFuture.completedFuture(null), executor).join();
    executor.shutdown();
}

答案 1 :(得分:1)

必须有理由说明为什么某些任务会在其他任务之后执行。这些原因应该以某种方式表示 - 作为消息或信号。当它们被明确表示时,您可以将类似json的符号转换为Dataflow diagram

要使库执行数据流图,请查看我的df4j2