The main function outputs only 1, 2 and 3. Why does the Runnable in thenRun not run and print 4 as well?
import java.util.concurrent.CompletableFuture;
import java.lang.Thread;
class CF {
static void doSomething() {
try {
Thread.sleep(100);
} catch(InterruptedException e) {
System.out.println("ggwp");
}
}
static CompletableFuture<Void> printAsync(int i) {
return CompletableFuture.runAsync(() -> {
doSomething();
System.out.print(i);
System.out.println(Thread.currentThread().getName());
});
}
public static void main(String[] args) {
printAsync(1).join();
CompletableFuture.allOf(printAsync(2), printAsync(3))
.thenRun(() -> printAsync(4));
doSomething();
}
}
However, when I change the doSomething function as shown below, all the numbers 1,2,3 and 4 will be printed.
static void doSomething() {
return;
}
CodePudding user response:
You invoke doSomething()
from printAsync()
and each invocation puts the invoking thread to sleep for 100ms. Therefore you don't wait long enough to see the output of 4
.
You can use join
as suggested in the comments to wait until all submitted tasks are finished. Or (to help understand what is happening) you can add a parameter to doSomething
to specify the amount of ms to sleep and wait a bit longer in your main thread, as shown below.
It is not that the printAsync(4)
is not executed. Rather, the jvm terminates the process because all non-daemon threads (in this case the main thread) are done before that point.
import java.util.concurrent.CompletableFuture;
import java.lang.Thread;
class CF {
static void doSomething(long sleep) {
try {
Thread.sleep(sleep);
} catch(InterruptedException e) {
System.out.println("ggwp");
}
}
static CompletableFuture<Void> printAsync(int i) {
return CompletableFuture.runAsync(() -> {
doSomething(100);
System.out.print(i);
System.out.println(Thread.currentThread().getName());
});
}
public static void main(String[] args) {
printAsync(1).join();
CompletableFuture.allOf(printAsync(2), printAsync(3))
.thenRun(() -> printAsync(4));
doSomething(500);
}
}
CodePudding user response:
As mentioned in the comments, .thenRun(() -> printAsync(4).join()).join();
will create another CompletableFuture
and complete it, giving you the expected output.