wax*_*cal 0 java multithreading callback
我正在尝试使用一些字符串创建一个非常简单的回调.IDE的代码意义在于对异常的未经检查的调用抱怨.任何人都可以给我一个解决方案吗?最后的想法是包装一个网络调用,以便返回承诺的结果,我可以根据需要添加其他功能.
import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class FuturesTest {
public static void main(String[] args) throws Exception {
new FuturesTest().go();
}
private void go() throws ExecutionException, InterruptedException {
CompletableFuture.supplyAsync(new MakesANetworkCall())
.whenComplete(new BiConsumer<String, String>() {
@Override
public void accept(String result, String s) {
System.out.println(result.toString());
}
})
.exceptionally(new Function<Exception, Exception>() {
@Override
public Exception apply(Exception e) {
e.printStackTrace();
return e;
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
System.out.println("Main thread will sleep");
Thread.sleep(2500);
System.out.println("Program over");
}
class MakesANetworkCall implements Supplier {
@Override
public String get() {
try {
System.out.println("Ground control to Major Tom");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// int i = 2/0;
return new String("Major Tom reporting!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
首先,您的类MakesANetworkCall实现原始类型Supplier而不是Supplier<String>.这将有效地禁用类型检查并隐藏您所做的所有错误,因此这不是您应该担心的单一警告,因为这不是代码中唯一的错误:
该BiConsumer传给whenComplete应该能够消耗Throwable作为其第二个参数.
在Function传递到exceptionally要消耗Throwable并返回一个替代的结果.
此外,您正在调用一个static使用表达式new CompletableFuture<String>()作为其目标的方法,并且您有一个过时的字符串创建表达式,就像new String("Major Tom reporting!")简单常量"Major Tom reporting!"所做的那样.通常,您似乎总是尝试使用不恰当的方法,即设计用于消耗您不使用的东西的方法,或者用于在没有方法的情况下提供值的方法.考虑一下:
CompletableFuture.supplyAsync(new MakesANetworkCall())
.thenAccept(result -> System.out.println(result))
.exceptionally(e -> { e.printStackTrace(); return null;})
.thenRun(()->System.out.println("Last action of all!"));
Run Code Online (Sandbox Code Playgroud)
这似乎是你的意图.如果确保MakesANetworkCall正确实现Supplier<String>,则应该编译而不发出任何警告.
您的核心问题在于class MakesANetworkCall implements Supplier {. 这是使用原始类型,因此隐藏了更多问题。解决这个问题class MakesANetworkCall implements Supplier<String> {并解决所有后续问题,您将得到:
CompletableFuture.supplyAsync(new MakesANetworkCall())
// Not <String, String>
.whenComplete(new BiConsumer<String, Throwable>() {
@Override
public void accept(String result, Throwable t) {
System.out.println(result);
}
})
// Not <Exception,Exception>
.exceptionally(new Function<Throwable, String>() {
@Override
public String apply(Throwable t) {
t.printStackTrace();
// Must return a Streing
return t.getMessage();
}
}
).thenApplyAsync(new Function<String, String>() {
@Override
public String apply(String o) {
System.out.println("Last action of all!");
return null;
}
});
Run Code Online (Sandbox Code Playgroud)