-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.java
109 lines (79 loc) · 4.02 KB
/
Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
public class Main {
// Process async operation with partial erro handling
// https://medium.com/@senanayake.kalpa/fantastic-completablefuture-allof-and-how-to-handle-errors-27e8a97144a0
static Random rand = new Random();
private static int getRandomNumber(int max) {
return Main.rand.nextInt(max) + 1;
}
// this is a task that receives parameters and returns a CompletableFuture
private static CompletableFuture<Long> powerNum( ExecutorService executor, Long num) {
return CompletableFuture.supplyAsync(() -> {
try {
int time = (2000);
Thread.sleep(time);
} catch (Exception e) {
}
if (num <= 50L) {
throw new IllegalArgumentException("You cannot power numbers below 50");
}
if (num <= 100L) {
throw new RuntimeException("You cannot power numbers below 100");
}
return num * num;
}, executor).exceptionally( e -> {
//Method handle additionally allows the stage to compute a replacement result that may enable further processing by other dependent stages.
//In all other cases, if a stage's computation terminates abruptly with an (unchecked) exception or error, then all dependent stages requiring its completion complete exceptionally as well,
//with a CompletionException holding the exception as its cause.
if (e.getCause() instanceof IllegalArgumentException) {
System.out.println("Handle for IllegalArgumentException : " + e.getMessage());
} else if (e.getCause() instanceof RuntimeException) {
System.out.println("Handle for RuntimeException : " + e.getMessage());
} else {
System.out.println("Handle for Any expcetion : " + e.getMessage());
}
return null;
});
}
public static void main(String[] args) throws Exception {
List<Long> list = new ArrayList<Long>();
for (int i = 0; i < 1800; i++) {
list.add(Long.valueOf(Main.getRandomNumber(1000)));
}
long tStart = System.currentTimeMillis();
// clamp the amount of thread we can deal with
ExecutorService executor = Executors.newFixedThreadPool(Math.max(1, Math.min(600, list.size())));
// tansform each task in a individual CompletableFuture
List<CompletableFuture<Long>> completableFutures = list.stream().map(num -> powerNum(executor, num)).collect(Collectors.toList());
CompletableFuture<Void> allFutures = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[completableFutures.size()]));
// join every response in to a list to result it in the end
CompletableFuture<List<Long>> allCompletableFuture = allFutures.thenApply(future -> {
return completableFutures.stream()
.map(completableFuture -> completableFuture.join())
.collect(Collectors.toList());
});
// get all the results of tasks
CompletableFuture completableFuture = allCompletableFuture.thenApply(longs -> {
return longs.stream().map(n -> {
if (n == null) {
return null;
}
return n;
}).collect(Collectors.toList());
});
List<Long> result = (List<Long>) completableFuture.get();
// release the "thread manager resource"
executor.shutdown();
long tEnd = System.currentTimeMillis();
System.out.println(result);
double elapsedSeconds = ((tEnd - tStart) / 1000.0);
System.out.println("Time: "+ elapsedSeconds + "s");
System.exit(0);
}
}