Reputation: 63
Is there a way to run getUsers()
asynchronously only from main()
in Java 8?
Running getUsers()
on the main thread would take 300 seconds. I wish to make it in less than 180 seconds with 4 cores.
public class Main {
// Getting users (with sleep)
public List<User> getUsers() {
List<User> users = new ArrayList();
for(int i = 0; i < 100; i++) {
users.add(new User("someName", "someAge"));
TimeUnit.MILLISECONDS.sleep(3000);
}
return users;
}
public static void main(String[] args) {
List<User> users = getUsers();
}
}
Without modifying getUsers()
(the objective), running the following is still taking 300 seconds:
public static void main(String[] args) {
List<User> users =
CompletableFuture.supplyAsync(() -> getUsers()).join();
}
Upvotes: 1
Views: 453
Reputation: 30685
You can divide your loop of users creation into smaller loops, and run them in parallel. Consider this example, which runs 4 times faster :
public static void main(String[] args) {
// create a pool executor of 4 threads, increase or decrease it if need
Executor executor = Executors.newFixedThreadPool(4);
CompletableFuture<List<User>> future1 = CompletableFuture.supplyAsync(() -> getUsers(25), executor);
CompletableFuture<List<User>> future2 = CompletableFuture.supplyAsync(() -> getUsers(25), executor);
CompletableFuture<List<User>> future3 = CompletableFuture.supplyAsync(() -> getUsers(25), executor);
CompletableFuture<List<User>> future4 = CompletableFuture.supplyAsync(() -> getUsers(25), executor);
List<User> allUsers = Stream.of(future1, future2, future3, future4)
.map(CompletableFuture::join)
.flatMap(List::stream)
.collect(Collectors.toList());
}
public static List<User> getUsers(int count) {
List<User> users = new ArrayList<>();
for (int i = 0; i < count; i++) {
users.add(new User("someName", "someAge"));
try {
TimeUnit.MILLISECONDS.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return users;
}
Upvotes: 1