Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java concurrency: Coordinating multiple tasks and have cancellation

Im looking for a good solution of coordinating several multithreading tasks.

Basically I have 2 tasks, I call A and B that need to be executed on a different thread than the main thread.

But B must be started after A has completed. A and B themselfes contain of several parts who should run parallel, called A1, A2, ... B1, B2, ....

And there is a caller from outside, who needs restart the whole job regardless of the progress. How can I archieve that? I thought of creating some sort of boolean array holding the information if each subtask (A1, ...) has already completed and if so start B. And check every few lines of code in each method if a cancellation has already been made. But it seems to me, that that is not an elegant solution and that there ways to coordinate excatly this.

enter image description here

like image 890
Paul Woitaschek Avatar asked Nov 01 '22 08:11

Paul Woitaschek


1 Answers

In Java8, you can use CompletableFutures. The method execA sets off three parallel tasks and returns a CompletableFuture which consists of all these tasks. execB waits for this composite task to complete and then sets off a set of tasks of its own. Finally, the get in the main method waits for the B methods to complete.

public class Futures {
    String name;
    int value;

    public static void main(String[] args) {
        try {
        execB(execA()).get();
        } catch(InterruptedException|ExecutionException e) {}
    }
    Futures(String name, int value) {
        this.name = name;
        this.value = value;
    }

    void runMethod() {
        System.out.println("Entering " + name);
        try {
            Thread.sleep(value * 1000);
        } catch(InterruptedException e) {}
        System.out.println("Exiting " + name);
    }
    public static CompletableFuture<Void> execA() {
        return(
            CompletableFuture.<Void>allOf(
            CompletableFuture.runAsync(() -> (new Futures("a1", 4)).runMethod()),
            CompletableFuture.runAsync(() -> (new Futures("a2", 2)).runMethod()),
            CompletableFuture.runAsync(() -> (new Futures("a3", 1)).runMethod()))
        );
    }
    public static CompletableFuture<Void> execB(CompletableFuture<Void> prev) {
        try {
            prev.get();
        } catch (InterruptedException|ExecutionException e) {}
        return(
            CompletableFuture.<Void>allOf(
            CompletableFuture.runAsync(() -> (new Futures("b1", 2)).runMethod()),
            CompletableFuture.runAsync(() -> (new Futures("b2", 3)).runMethod()),
            CompletableFuture.runAsync(() -> (new Futures("b3", 1)).runMethod())));
    }
}
like image 71
Neil Masson Avatar answered Nov 15 '22 03:11

Neil Masson