java Future小记,自用

it2023-05-24  83

文章参考 Future 详解

1. Future?异步?

在线程池中,我们知道调用future.get()方法是会阻塞当前线程,知道得到get方法的返回值之后才继续运行,所以future是异步编程?

线程池中的提交任务的方法有两种,一个是 execute,参数是 Runnable方法,返回值是 void方法; 第二种方式是 submit方法: 有三种 submit。这三种按照提交任务的类型来算分为两个类型。

提交执行 Runnable 类型的任务。

提交执行 Callable 类型的任务。

但是返回值都是 Future,这才是我们关心的东西。

在submit中可以通过传入参数得到返回值: 示例如下:

public class ThreadPoolExecutorTest { public static void main(String[] args) throws Exception { ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10)); AtomicInteger atomicInteger = new AtomicInteger(); Future<AtomicInteger> future = executor.submit(() -> { System.out.println("测试"); //在这里进行计算逻辑 atomicInteger.set(5201314); }, atomicInteger); System.out.println("future的内容:" + future.get()); Thread.currentThread().join(); //防止主线程退出 } }

其中调用的 get()方法是阻塞的,描述可得: 所以总结一下这种场景下返回的 Future 的不足之处:

只有主动调用 get 方法去获取值,但是有可能值还没准备好,就阻塞等待。

任务处理过程中出现异常会把异常隐藏,封装到 Future 里面去,只有调用 get 方法的时候才知道异常了。

2. Guava 中的 Future

增加了一个监听方法,执行完成后通知!!!

public static void main(String[] args) throws InterruptedException { // 1. 初始化executor ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newCachedThreadPool()); // 2. 要执行的任务 ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); return "化妆完毕!!"; }); // 3. 设置监听器函数执行回调 listenableFuture.addListener(() -> { try { System.out.println(Thread.currentThread().getName()+"-future的内容:" + listenableFuture.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }, executor); // 主线程任务,不会被阻塞 System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); }

另一种实现方法 FutureCallback 方式:

public class JDKThreadPoolExecutorTest { public static void main(String[] args) throws Exception { ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName()+"-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); return "化妆完毕了。"; }); Futures.addCallback(listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(@Nullable String result) { System.out.println(Thread.currentThread().getName()+"-future的内容:" + result); } @Override public void onFailure(Throwable t) { System.out.println(Thread.currentThread().getName()+"-女神放你鸽子了。"); t.printStackTrace(); } }); System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); } }

JDK1.8的CompletableFuture

/** * JDK1.8 提供的用于异步编程, 类似于流编程 */ public static void testJDK8CompletableFuture(){ CompletableFuture<Serializable> serializableCompletableFuture = CompletableFuture.supplyAsync(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return "妆化好了"; // 处理异常 }).handleAsync((result, exception) -> { if (exception != null) { System.out.println(Thread.currentThread().getName() + "-女神放你鸽子了!"); return exception.getCause(); } else { return result; } }).thenApplyAsync((returnStr) -> { System.out.println(Thread.currentThread().getName() + "-" + returnStr); return returnStr; }); System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。"); }

原文请看置顶连接

最新回复(0)