Neat Java 8 features - Concurrency API
This, the last of three posts is about the Java Concurrency API
Previous posts:
Concurrency API
The Concurrency API has been around for longer, but got some extra features with Java 8.
If you want to run tasks in parallel, wrap them either in a ‘Runnable’ (no return value) or a ‘Callable’ (has a return value). Submit these tasks to an ExecutorService and check the returned ‘Futures’ for completion, respectively get the results from them.
Here’s an example:
ExecutorService es = Executors.newWorkStealingPool();
List<Future<String>> futures = new ArrayList<Future<String>>();
for (int i=0; i<10; i++) {
Callable<String> task = () -> {
TimeUnit.SECONDS.sleep(1);
return "This callable was executed by "
+ Thread.currentThread().getName();
};
futures.add(es.submit(task));
}
while(!futures.stream().allMatch(f -> f.isDone())) {
TimeUnit.MILLISECONDS.sleep(100);
}
futures.stream().forEach(f -> {
try {
System.out.println(f.get());
} catch (Exception e) {
e.printStackTrace();
}
});
Here’s another example using a CompletionService. With the CompletionService you don’t have to loop over the Futures and check if they are ready, you can simple take the next one which is ready from the service.
Random random = new Random();
CompletionService<String> cs = new ExecutorCompletionService<String>(Executors.newWorkStealingPool());
for (int i=0; i<10; i++) {
Callable<String> task = () -> {
// wait for 1 to 10 sec
TimeUnit.SECONDS.sleep(random.nextInt(10)+1);
return "This callable was executed by "
+ Thread.currentThread().getName();
};
cs.submit(task);
}
int completed = 0;
while (completed < 10) {
// take the next one which is ready
Future<String> fut = cs.take();
System.out.println("Another one completed: "+fut.get());
completed++;
}