Skip to content

Commit ca7e2ca

Browse files
authored
Concurrency: Why Do We Need Completable Future? (#51)
* Add BasicSyntaxDemo * Add thread pool and futures * wip * Add link * Add link
1 parent 8716935 commit ca7e2ca

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ to see the complete list.
5151

5252
### Java Concurrency
5353

54+
- [Why Do We Need Completable Future?](https://mincong.io/2020/06/26/completable-future/)
5455
- [3 Ways to Handle Exception In Completable Future](https://mincong.io/2020/05/30/exception-handling-in-completable-future/)
5556
- [How CompletableFuture is tested in OpenJDK?](https://mincong.io/2020/05/10/completablefuture-test/)
5657

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.mincong.concurrency.completablefuture;
2+
3+
import java.util.concurrent.CompletableFuture;
4+
5+
/**
6+
* @author Mincong Huang
7+
* @blog https://mincong.io/2020/06/26/completable-future/
8+
*/
9+
public class BasicSyntaxDemo {
10+
public static void main(String[] args) {
11+
new BasicSyntaxDemo().run();
12+
}
13+
14+
private void run() {
15+
CompletableFuture //
16+
.runAsync(this::doStep1)
17+
.thenRun(this::doStep2)
18+
.thenRun(this::doStep3)
19+
.join();
20+
}
21+
22+
private void doStep1() {
23+
System.out.println("Step 1");
24+
}
25+
26+
private void doStep2() {
27+
System.out.println("Step 2");
28+
}
29+
30+
private void doStep3() {
31+
System.out.println("Step 3");
32+
}
33+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package io.mincong.concurrency;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.util.HashSet;
6+
import java.util.concurrent.*;
7+
import java.util.function.Consumer;
8+
import java.util.function.Function;
9+
import java.util.stream.Collectors;
10+
import java.util.stream.IntStream;
11+
import org.junit.jupiter.api.Test;
12+
13+
/**
14+
* @author Mincong Huang
15+
* @blog https://mincong.io/2020/06/26/completable-future/
16+
*/
17+
class BlogCompletableFutureMotivationTest {
18+
19+
/**
20+
* This test demonstrates that with {@link java.util.concurrent.Future}, there is no easy way to
21+
* perform callback action after the completion.
22+
*/
23+
@Test
24+
void threadPoolMultiTasks() throws Exception {
25+
var tasks =
26+
IntStream.range(0, 5)
27+
.mapToObj(i -> (Callable<Integer>) () -> i + 1)
28+
.collect(Collectors.toList());
29+
30+
var results = new HashSet<Integer>();
31+
var executor = Executors.newFixedThreadPool(3);
32+
try {
33+
var futures = executor.invokeAll(tasks);
34+
for (var f : futures) {
35+
int result = f.get();
36+
// perform callback
37+
results.add(result);
38+
}
39+
} finally {
40+
executor.shutdownNow();
41+
}
42+
43+
assertThat(results).containsExactly(1, 2, 3, 4, 5);
44+
}
45+
46+
@Test
47+
void completableFutureMultiTasks() throws Exception {
48+
var results = new ConcurrentSkipListSet<>();
49+
var tasks =
50+
IntStream.range(0, 5)
51+
.mapToObj(
52+
i ->
53+
CompletableFuture.completedFuture(i)
54+
// perform callback
55+
.thenApply(v -> v + 1)
56+
.thenAccept(results::add))
57+
.toArray(CompletableFuture[]::new);
58+
59+
var cf = CompletableFuture.allOf(tasks);
60+
cf.get();
61+
62+
assertThat(results).containsExactly(1, 2, 3, 4, 5);
63+
}
64+
65+
@Test
66+
void anotherExecutor() throws Exception {
67+
var executor = Executors.newSingleThreadExecutor();
68+
/*
69+
* Provide your executor to isolate long-running operation.
70+
*/
71+
var cf = CompletableFuture.supplyAsync(this::getSthSlow, executor);
72+
assertThat(cf.get()).isEqualTo(1);
73+
}
74+
75+
private int getSthSlow() {
76+
return 1;
77+
}
78+
79+
@Test
80+
void apply() throws Exception {
81+
// function
82+
Function<Integer, String> fn = String::valueOf;
83+
var s1 = fn.apply(1);
84+
assertThat(s1).isEqualTo("1");
85+
86+
// CF
87+
var s2 = CompletableFuture.completedFuture(1).thenApply(String::valueOf).get();
88+
assertThat(s2).isEqualTo("1");
89+
}
90+
91+
@Test
92+
void accept() throws Exception {
93+
// consumer
94+
Consumer<Integer> consumer = v -> assertThat(v).isEqualTo(1);
95+
consumer.accept(1);
96+
97+
// CF
98+
CompletableFuture.completedFuture(1).thenAccept(consumer).get();
99+
}
100+
}

0 commit comments

Comments
 (0)