Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java concurrency model - The Future Task

260 views

Published on

This document describes one of the most important topics of the Java Concurrency Model, the Future Task.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Java concurrency model - The Future Task

  1. 1. SOM-ITSOLUTIONS Java Java Concurrency Model - Future task SOMENATH MUKHOPADHYAY som-itsolutions #A2 1/13 South Purbachal Hospital Road Kolkata 700078 Mob: +91 9748185282 Email: ​som@som-itsolutions.com​ / ​som.mukhopadhyay@gmail.com Website:​ ​http://www.som-itsolutions.com/ Blog: ​www.som-itsolutions.blogspot.com
  2. 2. Note: Get the source code from ​https://github.com/sommukhopadhyay/FutureTask Callables and Future The FiutureTask is "A cancellable asynchronous computation. This class provides a base implementation of Future, with methods to start and cancel a computation, query to see if the computation is complete, and retrieve the result of the computation." Callables are just like Runnables to define the smallest unit of work called tasks. The difference between Callable and Runnable is that Runnable cannot return any result whereas Callable can return result of type Future. Later we can get the data from this return value. Once we submit the Callable task to the Executor, it does not block and returns immediately. We can determine if the task is finished or not by using the isDone api. Once isDone returns TRUE, we can access the result from the future which was returned from submitting the task to the executor using the future.get() API. However, we must remember that get API is blocking and hence if the task is not completed when the get has been called, it will block the thread. ExecutorService Actually FutureTask is designed to be used through the ExecutorService interface and the classes that implement it. It is those classes that use FutureTask and fork the threads and create non-blocking Asynchronous background task. Executors typically manage a pool of threads so that we don't have to create threads manually. All the threads in a thread-pool can be reused. The source code mentioned below is a working example of the use of FutureTask alongwith Executor model of the Java Concurrency Framework. The basic motto of the Application is the following. Suppose we need to do a very time consuming task at any time of an Application. Ay reading a big chunk of data from a huge database. So the basic idea is that whenever the application starts we spawn a background thread through the executor framework and delegate the task of reading data to that background thread. While reading of the data is going on, we continue with our other task in the application. The background thread collects the data and keep it in the future variable which is returned when we submit the task to the executor service. Any time of the application lifecycle we can know if the task is completed or not by calling the api ​isDone()​ on the future returned from submitting the task. Then in later time we can access the already fetched data by using the ​get()​ api on the future
  3. 3. variable which was returned when the task was submitted to the executor framework. Not only that, when the task is going on in the background we can cancel it at anytime we want. Hope this article comes handy to the learners of Java who are ready to deep dive in the world of concurrent programming. Class ProductInfo package​ ​com.somitsolutions.training.java.ExperimentationWithFutureTask​; public​ ​class​ ​ProductInfo​ ​{ ​private​ String productName​; ​private​ ​float​ productPrice​; ​public​ ​ProductInfo​(​String productName​,​ ​float​ productPrice​){ ​this​.​productName​ ​=​ productName​; ​this​.​productPrice​ ​=​ productPrice​; ​} ​public​ String ​getProductName​()​ ​{ ​return​ productName​; ​} ​public​ ​void​ ​setProductName​(​String productName​)​ ​{ ​this​.​productName​ ​=​ productName​; ​} ​public​ ​float​ ​getProductPrice​()​ ​{ ​return​ productPrice​; ​} ​public​ ​void​ ​setProductPrice​(​float​ productPrice​)​ ​{ ​this​.​productPrice​ ​=​ productPrice​; ​} } Class Preloader package ​com.somitsolutions.training.java.ExperimentationWithFutureTask​; import ​java.util.ArrayList​; import ​java.util.List​; import ​java.util.concurrent.ExecutionException​;
  4. 4. import ​java.util.concurrent.ExecutorService​; import ​java.util.concurrent.Executors​; import ​java.util.concurrent.FutureTask​; import ​java.util.concurrent.Callable​; public class ​Preloader​ ​{ static ExecutorService executor ​=​ Executors​.​newFixedThreadPool​(​1​); List​<​ProductInfo​>​ productInfo ​=​ new ArrayList​<​ProductInfo​>(); //The difference between Callable & Runnable //is that Callable can return a value (of type futuretask) private FutureTask​<​List​<​ProductInfo​>>​ future ​=​ null​; /*new FutureTask<List<ProductInfo>>(new LoadProductInfo());*/ public List​<​ProductInfo​>​ ​get​(){ //List<ProductInfo> retValue = null; try ​{ //get is blocking productInfo ​=​ future​.​get​(); }​ catch ​(​InterruptedException e​)​ ​{ // TODO Auto-generated catch block e​.​printStackTrace​(); }​ catch ​(​ExecutionException e​)​ ​{ // TODO Auto-generated catch block e​.​printStackTrace​(); } return productInfo​; } public ​boolean​ ​cancel​(){ return future​.​cancel​(​true​); } public ​boolean​ ​isDone​(){ return future​.​isDone​(); } //private final Thread thread = new Thread(future); public ​void​ ​start​()​ ​{ System​.​out​.​println​(​"The task is being submitted now..."​); //submit will return immediately. So we can do the other work //in the main thread. Later we can check if the task is //finished or not using isDone method.
  5. 5. future ​=​ ​(​FutureTask​<​List​<​ProductInfo​>>)​ ​(​executor​.​submit​(​new LoadProductInfo​())); } //long running task private List​<​ProductInfo​>​ ​loadProductInfo​(){ System​.​out​.​println​(​Thread​.​currentThread​().​getName​()); try ​{ Thread​.​sleep​(​10000​); }​ catch ​(​InterruptedException e​)​ ​{ // TODO Auto-generated catch block e​.​printStackTrace​(); } //As if this data we have got from //the database for ​(​int​ i ​=​ ​0​;​ i​<​100000​;​ i​++){ ProductInfo productI ​=​ new ProductInfo​(​Integer​.​toString​(​i​),​ i​); productInfo​.​add​(​productI​); } return productInfo​; } //The difference between Callable & Runnable //is that Callable can return a value (of type futuretask) class ​LoadProductInfo​ implements Callable​<​List​<​ProductInfo​>>{ @Override public List​<​ProductInfo​>​ ​call​()​ throws Exception ​{ // TODO Auto-generated method stub return loadProductInfo​(); } } } Class Main package​ ​com.somitsolutions.training.java.ExperimentationWithFutureTask​; import​ ​java.util.List​; public​ ​class​ ​Main​ ​{ public​ ​static​ ​void​ ​main​(​String​[]​ args​){ List​<​ProductInfo​>​ listOfProductInfo ​=​ ​null​;
  6. 6. System​.​out​.​println​(​Thread​.​currentThread​().​getName​()); Preloader preloader ​=​ ​new​ Preloader​(); //start getting the data in a background thread and //keep it for future use. while the background //thread is getting the data, we will continue //other task. later we can get this already fetched data //using future.get method. remember this get API is blocking preloader​.​start​(); /*//Do some other works... Here we are making the main thread sleep try { Thread.sleep(50000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ int​ count ​=​ ​0​; while​ ​(!​preloader​.​isDone​()){ System​.​out​.​println​(​"Task is yet to be completed..."​); count​++; try​ ​{ Thread​.​sleep​(​1000​); }​ ​catch​ ​(​InterruptedException e​)​ ​{ // TODO Auto-generated catch block e​.​printStackTrace​(); Preloader​.​executor​.​shutdown​(); System​.​exit​(​0​); }​ ​//sleep for 1 millisecond before checking again if​ ​(​count ​==​ ​100​){​//make the count == a low number say 8 //to see the cancellation effect preloader​.​cancel​(); System​.​out​.​println​(​"The task has been cancelled..."​); Preloader​.​executor​.​shutdown​(); System​.​exit​(​0​); } } if​(!​preloader​.​cancel​()​ ​&&​ preloader​.​isDone​()){ listOfProductInfo ​=​ preloader​.​get​(); } System​.​out​.​println​(​listOfProductInfo​.​get​(​0​).​getProductName​());
  7. 7. System​.​out​.​print​(​listOfProductInfo​.​get​(​0​).​getProductPrice​()); Preloader​.​executor​.​shutdown​(); } }

×