Java concurrency: FutureTask implements pre-loaded data to read e-books online, browsers to browse web pages, etc.

Keywords: Java network

Continue concurrent topics~

FutureTask is a bit like Runnable, and can be started through Thread, but FutureTask can return the executed data, and FutureTask's get method supports blocking.

Because: FutureTask can return the executed data, and FutureTask's get method supports blocking these two features, we can use it to pre-load some potentially used resources, and then call get method to get them when needed (if the resources are loaded, return directly; otherwise continue to wait for their load to complete).

Here are two examples:

1. Use FutureTask to preload the data to be used later.

  1. package com.zhy.concurrency.futuretask;  
  2.   
  3. import java.util.concurrent.Callable;  
  4. import java.util.concurrent.ExecutionException;  
  5. import java.util.concurrent.FutureTask;  
  6.   
  7. /** 
  8.  * Use FutureTask to load data in advance for later use 
  9.  *  
  10.  * @author zhy 
  11.  *  
  12.  */  
  13. public class PreLoaderUseFutureTask  
  14. {  
  15.     /** 
  16.      * Create a FutureTask to load resources 
  17.      */  
  18.     private final FutureTask<String> futureTask = new FutureTask<String>(  
  19.             new Callable<String>()  
  20.             {  
  21.                 @Override  
  22.                 public String call() throws Exception  
  23.                 {  
  24.                     Thread.sleep(3000);  
  25.                     return "Loading resources takes 3 seconds";  
  26.                 }  
  27.             });  
  28.   
  29.     public final Thread thread = new Thread(futureTask);  
  30.   
  31.     public void start()  
  32.     {  
  33.         thread.start();  
  34.     }  
  35.   
  36.     /** 
  37.      * Access to resources 
  38.      *  
  39.      * @return 
  40.      * @throws ExecutionException  
  41.      * @throws InterruptedException  
  42.      */  
  43.     public String getRes() throws InterruptedException, ExecutionException  
  44.     {  
  45.         return futureTask.get();//Return directly after loading, or wait for loading to finish.  
  46.   
  47.     }  
  48.   
  49.     public static void main(String[] args) throws InterruptedException, ExecutionException  
  50.     {  
  51.   
  52.         PreLoaderUseFutureTask task = new PreLoaderUseFutureTask();  
  53.         /** 
  54.          * Open preloaded resources 
  55.          */  
  56.         task.start();  
  57.         //Users perform other operations for 2 seconds before they really need to load resources  
  58.         Thread.sleep(2000);  
  59.   
  60.         /** 
  61.          * Access to resources 
  62.          */  
  63.         System.out.println(System.currentTimeMillis() + ": Start loading resources");  
  64.         String res = task.getRes();  
  65.         System.out.println(res);  
  66.         System.out.println(System.currentTimeMillis() + ": End of loading resources");  
  67.     }  
  68.   
  69. }  

Operation results:

  1. 1400902789275: Start loading resources
  2. It takes 3 seconds to load resources.
  3. 1400902790275: End of loading resources
As you can see, it takes 3 seconds to load resources, but now it only takes 1 second. If the user takes longer to do other operations, he can return directly, which greatly increases the user experience.

2. Look at Future's API


You can see that the API of Future is still simpler than the simple sense of knowing the name. Get (long, Time Unit) can also support, setting the maximum waiting time, such as an operation that takes too long, can be cancelled.

3. FutureTask simulation, pre-loading function for users to watch e-books Online

When the user watches the current page, the background loads the next page in advance, which can greatly improve the user's experience, without waiting for each page to load, the user will feel that the e-book software is very smooth, haha, the user feels good, is really good.

  1. package com.zhy.concurrency.futuretask;  
  2.   
  3. import java.util.concurrent.Callable;  
  4. import java.util.concurrent.ExecutionException;  
  5. import java.util.concurrent.FutureTask;  
  6.   
  7.   
  8. /** 
  9.  * Using FutureTask to simulate preloading the contents of the next page of the book 
  10.  *  
  11.  * @author zhy 
  12.  *  
  13.  */  
  14. public class BookInstance  
  15. {  
  16.   
  17.     /** 
  18.      * Current page number 
  19.      */  
  20.     private volatile int currentPage = 1;  
  21.   
  22.     /** 
  23.      * Asynchronous Tasks Get the Content of the Current Page 
  24.      */  
  25.     FutureTask<String> futureTask = new FutureTask<String>(  
  26.             new Callable<String>()  
  27.             {  
  28.                 @Override  
  29.                 public String call() throws Exception  
  30.                 {  
  31.                     return loadDataFromNet();  
  32.                 }  
  33.             });  
  34.   
  35.     /** 
  36.      * Instantiate a book and pass in the page number currently read 
  37.      *  
  38.      * @param currentPage 
  39.      */  
  40.     public BookInstance(int currentPage)  
  41.     {  
  42.         this.currentPage = currentPage;  
  43.         /** 
  44.          * Start the thread directly to get the current page number content 
  45.          */  
  46.         Thread thread = new Thread(futureTask);  
  47.         thread.start();  
  48.     }  
  49.   
  50.     /** 
  51.      * Get the content of the current page 
  52.      *  
  53.      * @return 
  54.      * @throws InterruptedException 
  55.      * @throws ExecutionException 
  56.      */  
  57.     public String getCurrentPageContent() throws InterruptedException,  
  58.             ExecutionException  
  59.     {  
  60.         String con = futureTask.get();  
  61.         this.currentPage = currentPage + 1;  
  62.         Thread thread = new Thread(futureTask = new FutureTask<String>(  
  63.                 new Callable<String>()  
  64.                 {  
  65.                     @Override  
  66.                     public String call() throws Exception  
  67.                     {  
  68.                         return loadDataFromNet();  
  69.                     }  
  70.                 }));  
  71.         thread.start();  
  72.         return con;  
  73.     }  
  74.   
  75.     /** 
  76.      * Grab data from the network according to page number 
  77.      *  
  78.      * @return 
  79.      * @throws InterruptedException 
  80.      */  
  81.     private String loadDataFromNet() throws InterruptedException  
  82.     {  
  83.         Thread.sleep(1000);  
  84.         return "Page " + this.currentPage + " : the content ....";  
  85.   
  86.     }  
  87.   
  88.     public static void main(String[] args) throws InterruptedException,  
  89.             ExecutionException  
  90.     {  
  91.         BookInstance instance = new BookInstance(1);  
  92.         for (int i = 0; i < 10; i++)  
  93.         {  
  94.             long start = System.currentTimeMillis();  
  95.             String content = instance.getCurrentPageContent();  
  96.             System.out.println("[1 Second reading time]read:" + content);  
  97.             Thread.sleep(1000);  
  98.             System.out.println(System.currentTimeMillis() - start);  
  99.         }  
  100.   
  101.     }  
  102. }  

Output results:

  1. [1 second reading time] read:Page 1: the content....
  2. 2001  
  3. [1 second reading time] read:Page 2: the content....
  4. 1000  
  5. [1 second reading time] read:Page 3: the content....
  6. 1001  
  7. [1 second reading time] read:Page 4: the content....
  8. 1000  
  9. [1 second reading time] read:Page 5: the content....
  10. 1001  

As you can see, besides the process of waiting for network loading data for the first time to view the current page (output: 2001, 1000 is loading time, 1000 is user reading time), the next pages are instantaneous returns (output 1000 is user reading time), there is no need to wait at all.

The code is to explain the application scenario of FutureTask, please do not use it directly in the project.

Posted by pchadwick83 on Sat, 25 May 2019 10:37:52 -0700