CompletableFuture引入
一、Future介绍
Future
以前我们如果有个方法action执行,比如去数据库中查询数据、上传一个文件等,这个方法执行10分钟,调用者就需要等10分钟。
基于此,调用者可以先执行action,返回一个票据future,然后可以继续做其他的事情,这样就不阻塞了,完全异步化。然后可以根据future拿到action的结果。
自己怎么实现一个Future呢?
代码例子:
package com.cy.java8; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; public class FutureInAction {
public static void main(String[] args) throws InterruptedException {
Future<String> future = invoke(() -> {
try {
Thread.sleep(10000);
return "I am finished";
} catch (InterruptedException e) {
return "error";
}
}); System.out.println(future.get());
System.out.println(future.get());
System.out.println(future.get());
//do other thing... while (!future.isDone()) {
Thread.sleep(10);
}
System.out.println(future.get());
} /**
* 以前阻塞式的方式
*
* @param callable
* @param <T>
* @return
*/
private static <T> T block(Callable<T> callable) {
return callable.action();
} /**
* Future异步方式
*
* @param callable
* @param <T>
* @return
*/
private static <T> Future<T> invoke(Callable<T> callable) {
AtomicReference<T> result = new AtomicReference<>();
AtomicBoolean finished = new AtomicBoolean(false);
Thread t = new Thread(() -> {
T value = callable.action();
result.set(value);
finished.set(true);
});
t.start(); Future<T> future = new Future<T>() {
@Override
public T get() {
return result.get();
} @Override
public boolean isDone() {
return finished.get();
}
};
return future;
} private interface Future<T> {
T get(); boolean isDone();
} private interface Callable<T> {
T action();
}
}
console打印:
null
null
null
I am finished
二、jdk自带的Future介绍
package com.cy.java8;
import java.util.concurrent.*;
public class FutureInAction2 {
public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
/**
* 创建了一个线程池,但这个线程池里面只有1根线程,单线程
* 这个线程是可以复用的,它执行完之后不会消失,会始终保持等待另外一个任务去执行
* 所以main函数执行结束之后,它不会退出的,所以还要shutdown
*/
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(() -> {
try {
Thread.sleep(10000);
return "I am finished.";
} catch (InterruptedException e) {
return "I am error.";
}
});
//do other thing...
/**
* jdk的future和我们自己写的不一样,它get的时候会阻塞住,如果没有结果它就阻塞住了,一直等结果
*/
//String value = future.get();
//System.out.println(value);
//最多等10秒,如果没有拿到结果就拉倒,抛TimeoutException
//String value2 = future.get(10000, TimeUnit.MILLISECONDS);
//System.out.println(value2);
while(!future.isDone()){
Thread.sleep(10);
}
System.out.println(future.get());
executorService.shutdown();
}
}
三、CompletableFuture引入
能不能future的任务执行完成之后,你来回调我呢?异步回调,你完成了之后来回调我。
就像ajax的异步回调,post请求完成之后回调函数,来执行其他的东西。
CompletableFuture最大的作用就是干这个的。
在讲CompletableFuture之前,先说下它的原理,自己模拟实现一个CompletableFuture.
模拟代码例子:
package com.cy.java8; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference; public class FutureInAction3 {
public static void main(String[] args) {
invoke(() -> {
try {
Thread.sleep(3000);
return "I am finished.";
} catch (InterruptedException e) {
return "I am error.";
}
}).setCompletable(new Completable<String>() {
@Override
public void complete(String s) {
System.out.println("complete. value = " + s);
} @Override
public void exception(Throwable e) {
System.out.println("error...");
e.printStackTrace();
}
}); //do other thing...
System.out.println("do other thing...");
} private static <T> Future<T> invoke(Callable<T> callable) {
AtomicReference<T> result = new AtomicReference<>();
AtomicBoolean finished = new AtomicBoolean(false); Future<T> future = new Future<T>() {
private Completable<T> completable; @Override
public T get() {
return result.get();
} @Override
public boolean isDone() {
return finished.get();
} @Override
public void setCompletable(Completable<T> completable) {
this.completable = completable;
} @Override
public Completable<T> getCompletable() {
return completable;
}
}; Thread t = new Thread(() -> {
try {
T value = callable.action();
result.set(value);
finished.set(true);
if (future.getCompletable() != null) {
future.getCompletable().complete(value);
}
} catch (Throwable cause) {
if (future.getCompletable() != null) {
future.getCompletable().exception(cause);
}
}
});
t.start(); return future;
} private interface Future<T> {
T get(); boolean isDone(); void setCompletable(Completable<T> completable); Completable<T> getCompletable();
} private interface Completable<T> {
void complete(T t); void exception(Throwable cause);
} private interface Callable<T> {
T action();
}
}
console打印:
do other thing...
complete. value = I am finished.
----
CompletableFuture引入的更多相关文章
- JAVA8给我带了什么——Optional和CompletableFuture
不管是JAVA,还是.NET.我们常常会看到空异常(NullPointerException).这种异常都是在运行的过程中出现.往往是变量是一个null值.但是你引用这个变量的后继字段或是方法.所以我 ...
- Future、 CompletableFuture、ThreadPoolTaskExecutor简单实践
一 Future(jdk5引入) 简介: Future接口是Java多线程Future模式的实现,可以来进行异步计算. 可以使用isDone方法检查计算是否完成,或者使用get阻塞住调用线程,直到计算 ...
- 006-优化web请求二-应用缓存、异步调用【Future、ListenableFuture、CompletableFuture】、ETag、WebSocket【SockJS、Stomp】
四.应用缓存 使用spring应用缓存.使用方式:使用@EnableCache注解激活Spring的缓存功能,需要创建一个CacheManager来处理缓存.如使用一个内存缓存示例 package c ...
- CompletableFuture
若你的意图是并发,而非并行,或者你的主要目标是在同一个CPU上执行几个松耦合的任务,充分利用CPU的核,让其足够忙碌,从而最大化程序的吞吐量,那么其实真正想做的避免因为等待远程服务的返回,或对数据库的 ...
- CompletableFuture 专题
/** * @Auther: cheng.tang * @Date: 2019/3/2 * @Description: */ package com.tangcheng.learning.concur ...
- Java 8 (10) CompletableFuture:组合式异步编程
随着多核处理器的出现,提升应用程序的处理速度最有效的方式就是可以编写出发挥多核能力的软件,我们已经可以通过切分大型的任务,让每个子任务并行运行,使用线程的方式,分支/合并框架(java 7) 和并行流 ...
- 有了 CompletableFuture,使得异步编程没有那么难了!
本文导读: 业务需求场景介绍 技术设计方案思考 Future 设计模式实战 CompletableFuture 模式实战 CompletableFuture 生产建议 CompletableFutur ...
- Java8系列 (七) CompletableFuture异步编程
概述 Java8之前用 Future 处理异步请求, 当你需要获取任务结果时, 通常的做法是调用 get(long timeout, TimeUnit unit) 此方法会阻塞当前的线程, 如果任务 ...
- Java8新特性--CompletableFuture
并发与并行 Java 5并发库主要关注于异步任务的处理,它采用了这样一种模式,producer线程创建任务并且利用阻塞队列将其传递给任务的consumer.这种模型在Java 7和8中进一步发展,并且 ...
随机推荐
- centso 7 Keepalived 配置脚本
#!/bin/bash #This is keepalived bashshell. #MASTER/BACKUP yum install -y openssl openssl-devel keepa ...
- Chrome OS 更新新版本可让Linux访问USB连接的Android设备
谷歌再次为Chrome OS带来了重大版本更新,使版本号达到了75.本次更新的一大亮点就是允许在Chrome OS上运行的Linux能够识别通过USB方式连接的Android设备,能够让用户使用Lin ...
- 最完美ThinkPHP Nginx 配置文件
一个配置文件,完美支持普通,兼容,pathinfo,rewrite4种url模式,别怪我没提醒你收藏哦. 常见的静态文件404时也不会再去跑一遍fastcgi浪费资源. server { listen ...
- 小米Air 13.3 安装Arch Linux
0. 前言 最近新买了一台小米Air 13.3,除了但键盘手感外都比较满意.我比较喜欢折腾Linux,但又不想放弃原有的Windows 10 Home,于是在原有的windows 10基础上再安装了A ...
- java8学习之Collector源码分析与收集器核心
之前已经对流在使用上已经进行了大量应用了,也就是说对于它的应用是比较熟悉了,但是比较欠缺的是对于它底层的实现还不太了解,所以接下来准备大量通过阅读官方的javadoc反过来加深对咱们已经掌握这些知识更 ...
- 心态炸了,我再写一个4.1.0版本的SND实例
maven依赖 <!-- Tests --><dependency> <groupId>org.springframework</groupId> &l ...
- Notepad++设置运行快捷键
python: 先按F5,之后将下面的命令保存,再设置快捷键. cmd /k c:\python27\python "$(FULL_CURRENT_PATH)" & PAU ...
- 【leetcode】740. Delete and Earn
题目如下: Given an array nums of integers, you can perform operations on the array. In each operation, y ...
- 【leetcode】1255. Maximum Score Words Formed by Letters
题目如下: Given a list of words, list of single letters (might be repeating) and score of every charact ...
- JAVA记录 Spring 两大特性
1.IOC控制反转 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...