1
public class main {
    private static class myClass {
        ...
    }

    public static MaxSubSequence Class1()) {
        ...
    }

    public static MaxSubSequence Class2() {
        ...
    }

    public static MaxSubSequence class3() {
        ...
    }

    public static MaxSubSequence class4() {
        ...

    }

    public static void main(String[] args) {
        Class1();
        Class2();
        Class3();
        Class4();
    }

}

In my example code above, I'm trying to calculate the CPU times for each function call in main. If I do:

long Start= System. nanoTime();
Class1();
long End= System.nanoTime();
long CPUTime=End-Start;

long Start= System. nanoTime();
Class2();
long End= System.nanoTime();
long CPUTime=End-Start;

long Start= System. nanoTime();
Class3();
long End= System.nanoTime();
long CPUTime=End-Start;

long Start= System. nanoTime();
Class4();
long End= System.nanoTime();
long CPUTime=End-Start;*

Then the CPU time will be wrong. I want to complete execution for Class1() first then Class2() then Class3() then Class4() like Async Await on Javascript but I don't know how to do it. Can someone help me on it please?

Thomas
  • 49
  • 5
  • This: https://www.baeldung.com/java-asynchronous-programming – Randy Casburn Jun 19 '21 at 01:26
  • Why would that be wrong? Are the functions doing something asynchronous? What’s wrong with the solutions offered in various tutorials found across the web? – Dave Newton Jun 19 '21 at 01:28
  • I don't understand why this would be wrong, although you've not provided the actual constructors for the classes so it's a bit hard to tell. – Layne Bernardo Jun 19 '21 at 01:31
  • @DaveNewton . It's wrong because the value of CPU time above is different from the value if I calculate each CPUTime separately. For the code above, the CPUTime of Class2() CLass3() and Class4() will be getting smaller and smaller – Thomas Jun 19 '21 at 01:40
  • 1
    That sounds like it could be perfectly normal in terms of how optimization works. More to the point, you're not adding up the CPU times in this code. – Louis Wasserman Jun 19 '21 at 01:52
  • 1
    Unless the code inside Class1, Class2, Class3 and Class4 are async, using another thread or something similar, the execution of each is completed before calling the next line. So the example you provided will work as you expected. If you cannot provide the code on the 4 classes, at least explain what kind of async execution you are making, from what you provided, the code is okay – Felipe Bonfante Jun 19 '21 at 01:58

2 Answers2

0

You can call the execution of method inside completable future and chain them all together. If I understood correctly here is how I tried to do it. Completable:join blocks until the execution is completed.

public class SimpleCompletableFutureSequence {

    static class MyClass {
        public String execute(String arg) {
            // this will be otherwise lengthy operation
            return arg;
        }

        public CalculatedTimedResponse executeAnother(String arg) {
            LocalTime startTime = LocalTime.now();
            LocalTime endTime = LocalTime.now();
            MyClass myClass = new MyClass();
            String response = null;
            try {
                response = myClass.execute(arg);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                endTime = LocalTime.now();
            }
            Duration timeDifference = Duration.between(startTime, endTime);
            System.out.println("Difference: " + timeDifference.toSecondsPart());
            return new CalculatedTimedResponse(timeDifference.toSecondsPart(), response);
        }
    }

    static CompletableFuture<String> class1() {
        return CompletableFuture.completedFuture(new MyClass().execute("class1"));
    }

    static CompletableFuture<String> class2() {
        return CompletableFuture.completedFuture(new MyClass().execute("class2"));
    }

    static CompletableFuture<String> class3() {
        return CompletableFuture.completedFuture(new MyClass().execute("class3"));
    }

    static CompletableFuture<String> class4() {
        return CompletableFuture.completedFuture(new MyClass().execute("class4"));
    }

    public static void main(String[] args) {
        List<CompletableFuture<String>> allFutures = Arrays.asList(class1(), class2(), class3(), class4());
        List<String> allResponse = allFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
        System.out.println(allResponse);
    }
}

If you are planning to calculate the time difference, then here is how I trie to do it:

static class CalculatedTimedResponse {
        int difference;
        String response;

        public CalculatedTimedResponse(int difference, String response) {
            this.difference = difference;
            this.response = response;
        }

        @Override
        public String toString() {
            return "CalculatedTimedResponse{" +
                    "difference=" + difference +
                    ", response='" + response + '\'' +
                    '}';
        }
    }

And 2 completable futures

static CompletableFuture<CalculatedTimedResponse> class1Response = CompletableFuture.supplyAsync(new Supplier<CalculatedTimedResponse>() {
        @Override
        public CalculatedTimedResponse get() {
            return new MyClass().executeAnother("time-execute- 1");
        }
    });

    static CompletableFuture<CalculatedTimedResponse> class2Response = CompletableFuture.supplyAsync(new Supplier<CalculatedTimedResponse>() {
        @Override
        public CalculatedTimedResponse get() {
            return new MyClass().executeAnother("time-execute- 2");
        }
    });
List<CompletableFuture<CalculatedTimedResponse>> timedFutures = Arrays.asList(class1Response, class2Response);
        List<CalculatedTimedResponse> allTimeResponse = timedFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
        System.out.println(allTimeResponse);

Source Code

silentsudo
  • 6,730
  • 6
  • 39
  • 81
0

First of all, as others have commented, unless the methods that you are invoking are doing something asynchronous, there is nothing special that you need to do.

As to why your numbers don't add up, there are multiple reasons. Basically, what you are doing is not a proper way to benchmark Java code, as there are optimizations, "warm-up periods", garbage collections, etc. that will skew the results.

The "proper" way to benchmark Java code is to use one of the existing tools written specifically to do benchmarks, such as JMH.

See, e.g. How do I write a correct micro-benchmark in Java?

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67