多线程相关知识 – CompletableFuture
public class TestCompletableFuture {
public static void main(String[] args) throws InterruptedException {
// 交给异步线程执行,
CompletableFuture<Double> completableFuture = CompletableFuture.supplyAsync(TestCompletableFuture::fetchPrice);
// 定义CompletableFuture完成时和异常时需要回调的实例,回调!!!
completableFuture.thenAccept((result) -> {
System.out.println(result);
});
CompletableFuture<Double> exceptionally = completableFuture.exceptionally((e) -> {
e.printStackTrace();
return null;
});
Thread.sleep(100);
}
static Double fetchPrice() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (Math.random() < 1) {
throw new RuntimeException("failed");
}
return 5 + Math.random() * 20;
}
// 此时也可以,但是需要静态方法,不然编译通不过
public static int fetchInt() {
return 1;
}
}
CompletableFuture 的优点是:
- 异步任务结束时,会自动回调某个对象的方法
- 异步任务出错时,会自动回调某个对象的方法;
- 主线程设置好回调后,不再关心异步任务的执行。
Supplier
接口规范:不需要是狗,长得像狗就行。 ---- 廖大大
java.util.function.Supplier 接口定义如下:
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
Supplier 接口相当简单,它不包含任何静态或默认方法,只有一个抽象方法 T get()。
为实现 Supplier 接口,需要提供一个不传入参数且返回泛型类型(generic type)的方法。根据 Javadoc 的描述,调用 Supplier 时,不要求每次都返回一个新的或不同的结果。Supplier 的一种简单应用是 Math.random 方法,它不传入参数且返回 double 型数据。如例所示,Math.random 方法可以被赋给 Supplier 引用并随时调用。
// 匿名内部类实现
DoubleSupplier doubleSupplier = new DoubleSupplier() {
@Override
public double getAsDouble() {
return Math.random();
}
};
// lambda 表达式
DoubleSupplier doubleSupplier2 = () -> Math.random();
/**
* 方法应用, 静态方法random() 方法符合get() 方法签名, 不一定是狗,长得像狗就行
* public static double random() {
* return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
* }
*/
DoubleSupplier doubleSupplier3 = Math::random;
java.util.function.Consumer 接口亦是如此
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
// 默认方法
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
使用如下:
// 在 java.util.concurrent.CompletableFuture#thenAccept 方法中作为传参数
public CompletableFuture<Void> thenAccept(Consumer<? super T> action) {
return uniAcceptStage(null, action);
}
// 使用时
completableFuture.thenAccept((result) -> {
System.out.println(result);
});
类似的还有 java.util.function.Function
@FunctionalInterface
public interface Function<T, R> {
/**
* 此时放心有两个类型,T 和 R, 传入放心参数T ,返回参数类型R
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
使用用例:
public CompletableFuture<T> exceptionally(
Function<Throwable, ? extends T> fn) {
return uniExceptionallyStage(fn);
}
// lambda 表达式 重写 apply(T t) 方法
completableFuture.exceptionally((e) -> {
e.printStackTrace();
return null;
});