java - 正确覆盖 CompletableFuture.cancel
问题描述
我注意到如果将来调用该方法,则覆盖该cancel
方法无效。thenApply
派生的未来不知道原来有这样一个覆盖的事实。下面的代码演示了这个问题。
有什么方法可以正确地覆盖该方法而不会失去改变未来的可能性?
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args){
CompletableFuture<Object> unmodified = new CompletableFuture<>(){
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("----> cancelling unmodified");
return super.cancel(mayInterruptIfRunning);
}
};
unmodified
.cancel(true);
CompletableFuture<Object> modified = new CompletableFuture<>(){
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("----> cancelling modified");
return super.cancel(mayInterruptIfRunning);
}
};
unmodified
.thenApply(x -> x)
.cancel(true);
System.out.println("----> end");
}
// OUTPUT
// > Task :Main.main()
// ----> cancelling unmodified
// ----> end
}
解决方案
您需要 Java 9 或更高版本。然后,所有创建新依赖未来的方法都将调用工厂方法newIncompleteFuture()
,您可以覆盖它:
public static void main(String arg[]) {
class MyFuture<T> extends CompletableFuture<T> {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
System.out.println("customized cancel");
return super.cancel(mayInterruptIfRunning);
}
@Override
public <U> CompletableFuture<U> newIncompleteFuture() {
return new MyFuture<>();
}
}
MyFuture<Object> future = new MyFuture<>();
System.out.print("direct: ");
future.cancel(true);
System.out.print("indirect: ");
future.thenApply(x -> x).cancel(true);
System.out.print("even longer chain: ");
future.thenApply(x -> x).exceptionally(t -> null).cancel(true);
System.out.println("end");
}
direct: customized cancel
indirect: customized cancel
even longer chain: customized cancel
end
但请记住,对于CompletableFuture
,取消与带有 a 的异常完成没有什么不同CancellationException
。所以,有人可以打电话completeExceptionally(new CancellationException())
而不是cancel(...)
, 达到同样的效果。
推荐阅读
- ios - 如何从详细视图控制器以编程方式推送视图控制器
- python-3.x - 为每个循环创建和添加行
- vba - VBA - Sharepoint 签出和签入非 excel 文件
- python - 在 Python 中使用最大似然推导回归系数
- laravel - Laravel 7.x Eloquent 递归关系 - 获取所有 id
- c# - 初始化 AggregateException 时抛出 ArrayTypeMismatchException
- javascript - 使用自定义函数打印对象的深拷贝
- xamarin.forms - 使用 Xamarin 和 Firebase 在 Web 视图应用程序上推送通知
- c# - 删除 Azure 应用程序见解中的警告“TelemetryConfiguration.Active 已过时”
- sql - 计算两个 GPS 坐标之间的距离时出错