Reputation: 23
I'm new to the java 8 Completablefuture, I'm trying to call Asynchronous methods in sequence order
my code:
public class Main {
public static void main(String[] args) {
System.out.println("CompletableFuture");
ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "single Thread"));
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(()-> print("thread 1"),e);
runT(voidCompletableFuture);
voidCompletableFuture.thenRunAsync(()->print("Thread 3"));
voidCompletableFuture.thenRun(e::shutdown);
}
public static void print(String threadName){
for(int i=1;i<=10;i++) {
System.out.println(threadName + ":" + i);
}
}
public static void runT(@NotNull CompletableFuture<Void> ayns){
ayns.thenRunAsync(()->print("Thread 2"));
}
}
But the code works different and call Asynchronous methods in non- sequence order.
the output:
CompletableFuture
thread 1:1
thread 1:2
thread 1:3
thread 1:4
thread 1:5
thread 1:6
thread 1:7
thread 1:8
thread 1:9
thread 1:10
Thread 2:1
Thread 3:1
Thread 3:2
Thread 3:3
Thread 3:4
Thread 3:5
Thread 3:6
Thread 3:7
Thread 3:8
Thread 3:9
Thread 3:10
Thread 2:2
Thread 2:3
Thread 2:4
Thread 2:5
Thread 2:6
Thread 2:7
Thread 2:8
Thread 2:9
Thread 2:10
As per the code logic "Thread1","Thread2","Thread3" need to execute but In the output "Thread 1" is called then "Thread 2" called but "Thread 2" is not completed but "Thread 3" is start execute, only "Thread 3" fully executed then "Thread 2" Start again.
My question is why does it happen? If my implementation is incorrect, please suggest me any method to implement this functionality in java 8.
Upvotes: 2
Views: 756
Reputation: 121048
You chain 3 different stages to one single voidCompletableFuture
:
thenRunAsync
thenRun
Of course they run in some undefined order. If you do want order, do not ignore the results from those methods and chain some dependent actions to them. For example:
voidCompletableFuture
.thenRunAsync(()->print("Thread 3"))
.thenRun(e::shutdown);
Methods like thenRunAsync
and thenRun
have a return type - do not ignore it (like you do).
In your case:
public static CompletableFuture<Void> runT(@NotNull CompletableFuture<Void> ayns){
CompletableFuture<Void> result = ayns.thenRunAsync(()->print("Thread 2"));
return result;
}
And properly chain it now:
CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(()-> print("thread 1"),e);
CompletableFuture<Void> newF = runT(voidCompletableFuture);
newF.thenRunAsync(()->print("Thread 3"));
.thenRun(e::shutdown);
Upvotes: 1