Summary

In this chapter, you learned the different mechanisms that you can use to work with tasks that return a result. These tasks are based on the Callable interface, which declares the call() method. This is a parameterized interface with the class returned by the call method.

When you execute a Callable task in an executor, you will always obtain an implementation of the Future interface. You can use this object to cancel the execution of the task, know if the task has finished its execution or get the result returned by the call() method.

You send Callable tasks to the executor using three different methods. With the submit() method, you send one task, and you will get immediately a Future object associated with this task. With the invokeAll() method, you send a list of tasks and will get a list of Future objects when all the tasks have finished its execution. With the invokeAny() method, you send a list of tasks, and you will receive the result (not a Future object) of the first task that finishes without throwing an exception. The rest of the tasks are canceled.

The Java concurrency API provides another mechanism to work with these kind of tasks. This mechanism is defined in the CompletionService interface and implemented in the ExecutorCompletionService class. This mechanism allows you to decouple the execution of tasks and the processing of their results. The CompletionService interface works internally with an executor and provides the submit() method to send tasks to the CompletionService interface and the poll() and take() methods to get the results of the tasks. These results are provided in the same order in which tasks finish their execution.

You also learned to implement these concepts with two real-world examples:

  • A best-matching algorithm using the UKACD dataset
  • An inverted index constructor, using a dataset with more than 1,00,000 documents with information of movies extracted from Wikipedia

In the next chapter, you will learn how to execute algorithms in a concurrent way that can be divided into phases, for example, a keyword extraction algorithm. You can implement that algorithm in the following three steps:

  1. Step 1 – parse all the documents and extract all the words.
  2. Step 2 – calculate the importance of each word on each document.
  3. Step 3 – obtain the best keywords.

The main characteristic of these steps is that you must finish one completely before you can start the next one. Java concurrency API provides the Phaser class to facilitate the concurrent implementation of these algorithms. It allows you to synchronize all the tasks involved on it at the end of a phase, so none of them will start the next one until all have finished the current one.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.65.241