一、Future介绍
Future
以前我们如果有个方法action执行,比如去数据库中查询数据、上传一个文件等,这个方法执行10分钟,调用者就需要等10分钟。
基于此,调用者可以先执行action,返回一个票据future,然后可以继续做其他的事情,这样就不阻塞了,完全异步化。然后可以根据future拿到action的结果。
自己怎么实现一个Future呢?
代码例子:
1 package com.cy.java8; 2 3 import java.util.concurrent.atomic.AtomicBoolean; 4 import java.util.concurrent.atomic.AtomicReference; 5 6 public class FutureInAction { 7 public static void main(String[] args) throws InterruptedException { 8 Future<String> future = invoke(() -> { 9 try { 10 Thread.sleep(10000); 11 return "I am finished"; 12 } catch (InterruptedException e) { 13 return "error"; 14 } 15 }); 16 17 System.out.println(future.get()); 18 System.out.println(future.get()); 19 System.out.println(future.get()); 20 //do other thing... 21 22 while (!future.isDone()) { 23 Thread.sleep(10); 24 } 25 System.out.println(future.get()); 26 } 27 28 /** 29 * 以前阻塞式的方式 30 * 31 * @param callable 32 * @param <T> 33 * @return 34 */ 35 private static <T> T block(Callable<T> callable) { 36 return callable.action(); 37 } 38 39 /** 40 * Future异步方式 41 * 42 * @param callable 43 * @param <T> 44 * @return 45 */ 46 private static <T> Future<T> invoke(Callable<T> callable) { 47 AtomicReference<T> result = new AtomicReference<>(); 48 AtomicBoolean finished = new AtomicBoolean(false); 49 Thread t = new Thread(() -> { 50 T value = callable.action(); 51 result.set(value); 52 finished.set(true); 53 }); 54 t.start(); 55 56 Future<T> future = new Future<T>() { 57 @Override 58 public T get() { 59 return result.get(); 60 } 61 62 @Override 63 public boolean isDone() { 64 return finished.get(); 65 } 66 }; 67 return future; 68 } 69 70 private interface Future<T> { 71 T get(); 72 73 boolean isDone(); 74 } 75 76 private interface Callable<T> { 77 T action(); 78 } 79 }
console打印:
null null null I am finished
二、jdk自带的Future介绍
1 package com.cy.java8; 2 3 import java.util.concurrent.*; 4 5 public class FutureInAction2 { 6 public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException { 7 /** 8 * 创建了一个线程池,但这个线程池里面只有1根线程,单线程 9 * 这个线程是可以复用的,它执行完之后不会消失,会始终保持等待另外一个任务去执行 10 * 所以main函数执行结束之后,它不会退出的,所以还要shutdown 11 */ 12 ExecutorService executorService = Executors.newSingleThreadExecutor(); 13 Future<String> future = executorService.submit(() -> { 14 try { 15 Thread.sleep(10000); 16 return "I am finished."; 17 } catch (InterruptedException e) { 18 return "I am error."; 19 } 20 }); 21 22 //do other thing... 23 24 /** 25 * jdk的future和我们自己写的不一样,它get的时候会阻塞住,如果没有结果它就阻塞住了,一直等结果 26 */ 27 //String value = future.get(); 28 //System.out.println(value); 29 30 //最多等10秒,如果没有拿到结果就拉倒,抛TimeoutException 31 //String value2 = future.get(10000, TimeUnit.MILLISECONDS); 32 //System.out.println(value2); 33 34 while(!future.isDone()){ 35 Thread.sleep(10); 36 } 37 System.out.println(future.get()); 38 39 executorService.shutdown(); 40 } 41 }
三、
----
原文:https://www.cnblogs.com/tenWood/p/11610284.html