BAEL-6578: CompletableFuture allOf.join() vs join()
This commit is contained in:
parent
296bba8657
commit
6fbb898059
|
@ -0,0 +1,112 @@
|
||||||
|
package com.baeldung.concurrent.completablefuture.allofvsjoin;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class CompletableFutureAllOffUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingJoin_thenBlocksThreadAndGetValue() {
|
||||||
|
CompletableFuture<String> future = waitAndReturn(1_000, "Harry");
|
||||||
|
assertEquals("Harry", future.join()); // waits one second
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingJoin_thenBlocksThreadAndThrowException() {
|
||||||
|
CompletableFuture<String> futureError = waitAndThrow(1_000);
|
||||||
|
assertThrows(RuntimeException.class, futureError::join); // waits one second
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingJoinTwoTimes_thenBlocksThreadAndGetValues() {
|
||||||
|
CompletableFuture<String> f1 = waitAndReturn(1_000, "Harry");
|
||||||
|
CompletableFuture<String> f2 = waitAndReturn(2_000, "Ron");
|
||||||
|
|
||||||
|
assertEquals("Harry", f1.join()); // waits for one second
|
||||||
|
assertEquals("Ron", f2.join()); // waits for one more second
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingAllOfJoin_thenBlocksThreadAndGetValues() {
|
||||||
|
CompletableFuture<String> f1 = waitAndReturn(1_000, "Harry");
|
||||||
|
CompletableFuture<String> f2 = waitAndReturn(2_000, "Ron");
|
||||||
|
|
||||||
|
CompletableFuture<Void> combinedFutures = CompletableFuture.allOf(f1, f2); // does NOT wait
|
||||||
|
combinedFutures.join(); // waits for two seconds
|
||||||
|
|
||||||
|
assertEquals("Harry", f1.join()); // does NOT wait
|
||||||
|
assertEquals("Ron", f2.join()); // does NOT wait
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingJoinInaLoop_thenProcessesDataPartially() {
|
||||||
|
CompletableFuture<String> f1 = waitAndReturn(1_000, "Harry");
|
||||||
|
CompletableFuture<String> f2 = waitAndThrow(2_000);
|
||||||
|
CompletableFuture<String> f3 = waitAndReturn(1_000, "Ron");
|
||||||
|
|
||||||
|
assertThrows(RuntimeException.class, () -> Stream.of(f1, f2, f3)
|
||||||
|
.map(CompletableFuture::join)
|
||||||
|
.forEach(this::sayHello));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingAllOfJoin_thenFailsForAll() {
|
||||||
|
CompletableFuture<String> f1 = waitAndReturn(1_000, "Harry");
|
||||||
|
CompletableFuture<String> f2 = waitAndThrow(2_000);
|
||||||
|
CompletableFuture<String> f3 = waitAndReturn(1_000, "Ron");
|
||||||
|
|
||||||
|
assertThrows(RuntimeException.class, () -> CompletableFuture.allOf(f1, f2, f3)
|
||||||
|
.join());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenCallingExceptionally_thenRecoversWithDefaultValue() {
|
||||||
|
CompletableFuture<String> f1 = waitAndReturn(1_000, "Harry");
|
||||||
|
CompletableFuture<String> f2 = waitAndThrow(2_000);
|
||||||
|
CompletableFuture<String> f3 = waitAndReturn(1_000, "Ron");
|
||||||
|
|
||||||
|
CompletableFuture<String> names = CompletableFuture.allOf(f1, f2, f3)
|
||||||
|
.thenApply(__ -> f1.join() + "," + f2.join() + "," + f3.join())
|
||||||
|
.exceptionally(err -> {
|
||||||
|
System.out.println("oops, there was a problem! " + err.getMessage());
|
||||||
|
return "names not found!";
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals("names not found!", names.join());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sayHello(String name) {
|
||||||
|
System.out.println(LocalDateTime.now() + " - " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<String> waitAndReturn(long millis, String value) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
// Thread.sleep() is commented to avoid slowing down the pipeline
|
||||||
|
// Thread.sleep(millis);
|
||||||
|
return value;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<String> waitAndThrow(long millis) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try {
|
||||||
|
// Thread.sleep() is commented to avoid slowing down the pipeline
|
||||||
|
// Thread.sleep(millis);
|
||||||
|
} finally {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue