In this article, we will learn how to implement tasks that return a result and run them on an executor using Callable and Future interfaces with the help Executor framework. This post is continuation of previous post where we learned about cached Thread pool
One of the advantages of the Executor framework is that you can run concurrent tasks that return a result. The Java Concurrency API achieves this with the following two interfaces:
Create a class named FactCalculator that implements the Callable interface parameterized with the Integer type
Implement the Main class
Output
Number of completed task : 0
Task 0 status : false
Task 1 status : false
Task 2 status : false
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 1
Task 0 status : true
Task 1 status : false
Task 2 status : false
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 2
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 3
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 3
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 4
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 4
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 6
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : false
Task 6 status : true
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 6
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Main result :
Result of Task: 0 2
Result of Task: 1 120
Result of Task: 2 6
Result of Task: 3 720
Result of Task: 4 362880
Result of Task: 5 362880
Result of Task: 6 2
Result of Task: 7 24
Result of Task: 8 40320
Result of Task: 9 40320
How it works...
In this example, we have learned how to use the Callable interface to launch concurrent tasks that return a result. You have implemented the FactorialCalculator class that implements the Callable interface with Integer as the type of the result. Hence, it returns before type of the call() method.
The other important point of this example is in the Main class. You send a Callable object to be executed in an executor using the submit() method. This method receives a Callable object as a parameter and returns a Future object that you can use with two main objectives
get(long timeout, TimeUnit unit): This version of the get method, if the result of the task isn't available, waits for it for the specified time. If the specified period of time passes and the result isn't yet available, the method returns a null value. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS.
That's all. Thanks for reading this and if you found this article useful, I would like to see your appreciation in the form of comments.
If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...
One of the advantages of the Executor framework is that you can run concurrent tasks that return a result. The Java Concurrency API achieves this with the following two interfaces:
- Callable: This interface has the call() method. In this method, you have to implement the logic of a task. The Callable interface is a parameterized interface, meaning you have to indicate the type of data the call() method will return.
- Future: This interface has some methods to obtain the result generated by a Callable object and to manage its state
Create a class named FactCalculator that implements the Callable interface parameterized with the Integer type
Implement the Main class
Output
Number of completed task : 0
Task 0 status : false
Task 1 status : false
Task 2 status : false
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 1
Task 0 status : true
Task 1 status : false
Task 2 status : false
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 2
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 3
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : false
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 3
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 4
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : false
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 4
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : false
Task 6 status : false
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 6
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : false
Task 6 status : true
Task 7 status : false
Task 8 status : false
Task 9 status : false
Number of completed task : 6
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Number of completed task : 8
Task 0 status : true
Task 1 status : true
Task 2 status : true
Task 3 status : true
Task 4 status : true
Task 5 status : true
Task 6 status : true
Task 7 status : true
Task 8 status : false
Task 9 status : false
Main result :
Result of Task: 0 2
Result of Task: 1 120
Result of Task: 2 6
Result of Task: 3 720
Result of Task: 4 362880
Result of Task: 5 362880
Result of Task: 6 2
Result of Task: 7 24
Result of Task: 8 40320
Result of Task: 9 40320
How it works...
In this example, we have learned how to use the Callable interface to launch concurrent tasks that return a result. You have implemented the FactorialCalculator class that implements the Callable interface with Integer as the type of the result. Hence, it returns before type of the call() method.
The other important point of this example is in the Main class. You send a Callable object to be executed in an executor using the submit() method. This method receives a Callable object as a parameter and returns a Future object that you can use with two main objectives
- You can control the status of the task: you can cancel the task and check if it has finished. For this purpose, you have used the isDone() method to check if the tasks had finished.
- You can get the result returned by the call() method. For this purpose, you have used the get() method. This method waits until the Callable object has finished the execution of the call() method and has returned its result. If the thread is interrupted while the get() method is waiting for the result, it throws an InterruptedException exception. If the call() method throws an exception, this method throws an ExecutionException exception.
There's more...
When you call the get() method of a Future object and the task controlled by this object hasn't finished yet, the method blocks until the task finishes. The Future interface provides another version of the get() method.
get(long timeout, TimeUnit unit): This version of the get method, if the result of the task isn't available, waits for it for the specified time. If the specified period of time passes and the result isn't yet available, the method returns a null value. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS.
That's all. Thanks for reading this and if you found this article useful, I would like to see your appreciation in the form of comments.
If you know anyone who has started learning Java, why not help them out! Just share this post with them. Thanks for studying today!...