Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在CompletableFuture中使用Supplier会产生与使用lambda不同的结果_Java_Lambda_Java 8_Completable Future - Fatal编程技术网

Java 在CompletableFuture中使用Supplier会产生与使用lambda不同的结果

Java 在CompletableFuture中使用Supplier会产生与使用lambda不同的结果,java,lambda,java-8,completable-future,Java,Lambda,Java 8,Completable Future,我创建了一个读取文本文件并使用CompletableFuture包装调用的小示例 public class Async { public static void main(String[] args) throws Exception { CompletableFuture<String> result = ReadFileUsingLambda(Paths.get("path/to/file")); result.whenComplete((

我创建了一个读取文本文件并使用
CompletableFuture
包装调用的小示例

public class Async {
    public static void main(String[] args) throws Exception {
        CompletableFuture<String> result = ReadFileUsingLambda(Paths.get("path/to/file"));
        result.whenComplete((ok, ex) -> {
            if (ex == null) {
                System.out.println(ok);
            } else {
                ex.printStackTrace();
            }
        });
    }

    public static CompletableFuture<String> ReadFileUsingSupplier(Path file) throws Exception {
        return CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try {
                    return new String(Files.readAllBytes(file));
                } catch (IOException e) {
                    e.printStackTrace();
                    return "test";
                }
            }
        }, ForkJoinPool.commonPool());
    }

    public static CompletableFuture<String> ReadFileUsingLambda(Path file) throws Exception {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return new String(Files.readAllBytes(file));
            } catch (IOException e) {
                e.printStackTrace();
                return "test";
            }
        } , ForkJoinPool.commonPool());
    }
}
公共类异步{
公共静态void main(字符串[]args)引发异常{
CompletableFuture result=ReadFileUsingLambda(path.get(“path/to/file”);
结果。完成时((确定,ex)->{
如果(ex==null){
系统输出打印项次(ok);
}否则{
例如printStackTrace();
}
});
}
公共静态CompletableFuture ReadFileUsingSupplier(路径文件)引发异常{
返回CompletableFuture.SupplySync(新供应商(){
@凌驾
公共字符串get(){
试一试{
返回新字符串(Files.readAllBytes(file));
}捕获(IOE异常){
e、 printStackTrace();
返回“测试”;
}
}
},ForkJoinPool.commonPool());
}
公共静态CompletableFuture ReadFileUsingLambda(路径文件)引发异常{
返回CompletableFuture.SupplySync(()->{
试一试{
返回新字符串(Files.readAllBytes(file));
}捕获(IOE异常){
e、 printStackTrace();
返回“测试”;
}
},ForkJoinPool.commonPool());
}
}
此代码不返回任何内容。它执行并且“什么都没有发生”,没有错误或输出。如果我调用
ReadFileUsingSupplier
而不是
ReadFileUsingLambda
,那么我会在控制台中打印文件内容


对我来说,这没有意义,因为lambda是编写内联函数的简写,它不应该改变行为,但在本例中,它显然改变了行为。

我认为这只是执行时间的问题-lambda可能需要更多的时间来执行,允许程序在读取文件之前退出

试试这个:

  • 添加
    线程睡眠(1000)
    作为
    ReadFileUsingSupplier
    中try块中的第一条语句,您将看不到任何输出
  • 添加
    线程睡眠(1000)ReadFileUsingLambda
    时,代码>位于主文件末尾,您将看到预期的输出
要确保在未来完成之前不会退出main,您可以调用:

result.join();

如前所述,在任何情况下都需要result.join(),以避免主线程退出过快

当JVM升温时,使用lambdas vs匿名闭包似乎会受到惩罚,此后性能是相同的。我在上找到了这些信息,而这又是链接

顺便说一句,用Thread.sleep()来解决奇怪的计时问题从来都不是一个好主意。当你或其他人重新阅读时,找出原因并采取适当的措施会更加清晰

System.out.println(result.get(5, TimeUnit.SECONDS));

这使您也可以放弃.join()。

谢谢。这确实起到了作用,但接下来我如何确保我的程序不会退出,直到我从CompletableFuture@SulAga您只需调用
result.get()
result.join()
,那么join或get是一个阻塞调用?它是主线程上的阻塞还是CompletableFuture线程上的阻塞?这是个问题吗。blocking@SulAga它在调用它的线程上阻塞-如果您只是在
main
的末尾添加
result.join()
,它将阻塞主线程。