首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >thenApply in CompletableFuture

thenApply in CompletableFuture
EN

Stack Overflow用户
提问于 2017-09-22 11:24:28
回答 2查看 1.1K关注 0票数 0

在以下代码中

代码语言:javascript
运行
复制
public CompletableFuture<String> getMyFuture(String input)
    {   
        CompletableFuture<String> future = new CompletableFuture<String>().thenApply((result) -> result+ "::");
        ExecutorService service = Executors.newFixedThreadPool(6);
        service.submit(() -> {      
            try {
                future.complete(getResult(input));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        return future;
    }

    public String getResult(String input) throws InterruptedException
    {
        Thread.sleep(3000);
        return "hello "+ input +" :" + LocalTime.now();
    }

我期望输出包含尾随"::“但是程序不是"hello first :16:49:30.231”,我的应用程序实现正确吗?

EN

回答 2

Stack Overflow用户

发布于 2017-09-22 11:40:50

您正在调用在第一行获得的CompletionStageCompletionStage方法(在这里您调用"thenApply“方法)。

如果您的目的是使用一些字符串值( CompletableFuture )来完成future.complete(getResult(input)),然后应用一些函数,那么最好将thenApply()放在末尾(返回未来的位置)。

代码语言:javascript
运行
复制
public CompletableFuture<String> getMyFuture(String input)
    {
        CompletableFuture<String> future = new CompletableFuture<String>();
        ExecutorService service = Executors.newFixedThreadPool(6);
        service.submit(() -> {
            try {
                future.complete(getResult(input));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        return future.thenApply(result -> result+ "::");
    }

我不知道怎么用更容易理解的方式来解释。但是简单地说:您在complete()中调用错误的对象引用的Runnable方法。

票数 2
EN

Stack Overflow用户

发布于 2017-09-22 15:34:36

您正在创建两个CompletableFuture实例。第一种是通过new CompletableFuture<String>()创建的,它永远不会完成,您甚至不会保留对它的引用,从而使完成它成为可能。

第二个函数是通过对第一个函数调用.thenApply((result) -> result+ "::")创建的,它可以在第一个函数完成后通过计算指定的函数来完成,使用第一个函数的结果作为函数的参数。但是,由于第一个函数从未完成,函数就变得不相关了。

但是CompletableFuture实例可以由任何人完成,而不仅仅是传递给链接方法的函数。完成的可能性甚至显着地显示在它的类名中。在多次完成尝试的情况下,一个将成为第一个,赢得比赛,所有后续的完成尝试都将被忽略。在您的代码中,您只有一次完成尝试,它将使用getResult返回的值成功地完成它,而没有任何适应。

您可以更改代码,将对第一个CompletableFuture实例的引用手动保存为complete,以便使用传递给thenApply的函数完成第二个实例,但另一方面,这里不需要手动完成:

代码语言:javascript
运行
复制
public CompletableFuture<String> getMyFuture(String input) {   
    ExecutorService service = Executors.newFixedThreadPool(6);
    return CompletableFuture.supplyAsync(() -> getResult(input), service)
                            .thenApply(result -> result + "::");
}
public String getResult(String input) {
    LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));
    return "hello "+ input +" :" + LocalTime.now();
}    

当将执行器指定为supplyAsync时,将使用该执行器计算函数。不需要更多。

不用说,这只是举个例子。您不应该创建临时线程池执行器,因为线程池执行器的全部目的是允许重用线程(而且您只使用这六个线程中的一个),并且在使用之后应该关闭它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46363626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档