FutureTask

    xiaoxiao2022-07-03  108

    1.  Future

    一个Future代表一个异步计算的结果。Future提供检查计算是否完成、等待计算完成并获取计算结果的方法。只有当计算完成以后,才可以使用get方法检索结果,否则将会阻塞直到计算完成。通过调研cancel方法可以取消执行。另外,还提供了检查任务是正常完成还是被取消的方法。一旦计算完成,这个计算不能被取消。

    简单用法:

    1 public class App { 2 ExecutorService executorService = Executors.newFixedThreadPool(3); 3 ArchiveSearcher searcher = new ArchiveSearcher(); 4 5 void showSearch(final String target) throws InterruptedException { 6 Future<String> future = executorService.submit(new Callable<String>() { 7 public String call() { 8 return searcher.search(target); 9 } 10 }); 11 12 displayOtherThings(); // do other things while searching 13 14 try { 15 displayText(future.get()); // use future 16 } catch (ExecutionException ex) { 17 cleanup(); 18 return; 19 } 20 } 21 }

    FutureTask类是Future的实现,它同时也实现了Runnable,因此也可以被Executor执行。例如,上面的代码可以被改写成如下:

    1 FutureTask<String> future = new FutureTask<String>(new Callable<String>() { 2 public String call() { 3 return searcher.search(target); 4 } 5 }); 6 executor.execute(future);

    2.  FutureTask 

    一个可取消的异步计算该类提供了Future的基本实现,提供了启动和取消计算、查询计算是否完成以及检索计算结果的方法只有在计算完成后才可检索结果;如果计算尚未完成,get方法将阻塞计算完成以后,计算不能重启或取消(除非调用runAndReset方法) 

    一个FutureTask可以用来包装一个Callable或Runnable对象。因为FutureTask实现了Runnable接口,一个FutureTask可以被提交给一个Executor来执行。 

    3.  示例

    1 package com.cjs.example; 2 3 import java.util.concurrent.*; 4 5 /** 6 * @author ChengJianSheng 7 * @date 2019-05-22 8 */ 9 public class App { 10 11 public static void main(String[] args) throws Exception { 12 13 long t1 = System.currentTimeMillis(); 14 15 ExecutorService executorService = Executors.newFixedThreadPool(3); 16 17 FutureTask<String> heatUpWaterFuture = new FutureTask<String>(new Callable<String>() { 18 @Override 19 public String call() throws Exception { 20 System.out.println("烧开水..."); 21 Thread.sleep(3000); 22 return "ok"; 23 } 24 }); 25 26 27 FutureTask<String> cookMealsFuture = new FutureTask<String>(new Callable<String>() { 28 @Override 29 public String call() throws Exception { 30 System.out.println("煮饭..."); 31 Thread.sleep(5000); 32 return "ok"; 33 } 34 }); 35 36 executorService.submit(heatUpWaterFuture); 37 executorService.submit(cookMealsFuture); 38 39 System.out.println("炒菜..."); 40 41 Thread.sleep(2000); 42 43 System.out.println("菜炒好了了"); 44 45 if (heatUpWaterFuture.get(5000, TimeUnit.SECONDS) == "ok" 46 && cookMealsFuture.get(5000, TimeUnit.SECONDS) == "ok") { 47 System.out.println("开饭了..."); 48 } 49 50 long t2 = System.currentTimeMillis(); 51 System.out.println("做饭用时:" + (t2-t1) + "ms"); 52 53 } 54 } 

    输出

    1 烧开水... 2 煮饭... 3 炒菜... 4 菜炒好了了 5 开饭了... 6 做饭用时:5014ms 

    在实际开发过程中,将那些耗时较长,且可以并行的操作都封装成一个FutureTask

    如果有想学习java的程序员,可来我们的java学习扣qun:830783865,免费送java的视频教程噢!我每晚上8点还会在群内直播讲解Java知识,欢迎大家前来学习哦

    最新回复(0)