当前位置: 首页 > 知识库问答 >
问题:

方法调用Future.get()块。这真的值得吗?

晁国发
2023-03-14

请仔细阅读问题,然后再将其标记为副本。

下面是伪代码的片段。我的问题是-下面的代码是否不违背并行异步处理的概念?

我问这个问题的原因是,在下面的代码中,主线程将提交一个要在不同线程中执行的任务。在队列中提交任务后,它会阻止Future.get()方法返回值。我宁愿让任务在主线程中执行,而不是提交到另一个线程并等待结果。通过在新线程中执行任务,我得到了什么?

我知道你可以等一段有限的时间等等,但是如果我真的在乎结果呢?如果要执行多个任务,问题会变得更糟。在我看来,我们只是在同步地做这项工作。我知道Guava库提供了一个非阻塞侦听器接口。但是我很想知道我的理解对未来是否正确。如果它是正确的,为什么Future.get()被设计为阻止整个并行处理过程?

注意-为了记录,我使用JAVA 6

public static void main(String[] args){

private ExectorService executorService = ...

Future future = executorService.submit(new Callable(){
    public Object call() throws Exception {
        System.out.println("Asynchronous Callable");
        return "Callable Result";
    }
});

System.out.println("future.get() = " + future.get());
}

共有3个答案

吕学
2023-03-14

我想就这一点发表我的观点,更多的是理论观点,因为已经有了一些技术上的答案。我的回答基于以下评论:

让我给你举个例子。我提交给服务的任务最终会引发HTTP请求,HTTP请求的结果可能需要很多时间。但是我确实需要每个HTTP请求的结果。任务在循环中提交。如果我等待每个任务返回(get),那么我在这里失去了并行性,不是吗?

这与问题中所说的一致。

假设你有三个孩子,你想做一个蛋糕,作为生日礼物。因为你想做最好的蛋糕,你需要很多不同的材料来准备。所以你要做的就是把配料分在三个不同的清单上,因为你居住的地方只有三家超市出售不同的产品,同时给你的每个孩子分配一项任务。

现在,在你开始准备蛋糕之前(让我们再次假设,你需要事先准备好所有的配料),你必须等待孩子们完成最长的路线。现在,在开始做蛋糕之前,你需要等待所有的配料,这是你的需要,而不是任务之间的依赖。你的孩子尽可能长时间地同时完成任务(例如:直到第一个孩子完成任务)。所以,总结一下,这里有平行性。

当您有一个孩子,并且您将所有三项任务分配给他/她时,将描述顺序示例。

楚硕
2023-03-14

下面是伪代码的片段。我的问题是-下面的代码没有击败并行异步处理的概念吗?

这完全取决于你的用例:

>

  • 如果你真的想阻止直到你得到结果,使用阻止get()

    如果您可以等待特定时间段来了解状态,而不是无限阻塞持续时间,请使用带超时的get()

    如果您可以在不立即分析结果的情况下继续,并在将来检查结果,请使用CompletableFuture(java 8)

    一个可以显式完成的Future(设置其值和状态),并可用作CompletionLevel,支持完成后触发的相关函数和操作。

    您可以从Runnable/Callable实现回调机制。请看下面的问题:

    Java执行者:当任务完成时,如何在没有阻塞的情况下得到通知?

  • 姚钊
    2023-03-14

    Future为您提供了方法isDone(),该方法不阻塞,如果计算已完成,则返回true,否则返回false。

    Future.get()用于检索计算结果。

    你有几个选择:

    • 调用isDone(),如果结果准备好了,请通过调用get()来请求它,注意没有阻塞
    • 块无限期与get()
    • 块指定的超时与get(长超时,TimeUnit单位)

    整个Future API都有从执行并行任务的线程中获取值的简单方法。如果您愿意,可以同步或异步完成,如上面的项目符号所述。

    使用缓存更新示例

    下面是一个来自Java并发性的缓存实现,它是未来的一个优秀用例。

    • 如果计算已经在运行,对计算结果感兴趣的调用方将等待计算完成
    • 如果缓存中的结果已准备就绪,则调用者将收集该结果
    • 如果结果尚未准备好且计算尚未开始,则调用者将开始计算并将结果包装到其他调用者的Future

    这一切都可以通过FutureAPI轻松实现。

    package net.jcip.examples;
    
    import java.util.concurrent.*;
    /**
     * Memoizer
     * <p/>
     * Final implementation of Memoizer
     *
     * @author Brian Goetz and Tim Peierls
     */
    public class Memoizer <A, V> implements Computable<A, V> {
        private final ConcurrentMap<A, Future<V>> cache
                = new ConcurrentHashMap<A, Future<V>>();
        private final Computable<A, V> c;
    
    public Memoizer(Computable<A, V> c) {
        this.c = c;
    }
    
    public V compute(final A arg) throws InterruptedException {
        while (true) {
    
            Future<V> f = cache.get(arg);
            // computation not started
            if (f == null) {
                Callable<V> eval = new Callable<V>() {
                    public V call() throws InterruptedException {
                        return c.compute(arg);
                    }
                };
    
                FutureTask<V> ft = new FutureTask<V>(eval);
                f = cache.putIfAbsent(arg, ft);
                // start computation if it's not started in the meantime
                if (f == null) {
                    f = ft;
                    ft.run();
                }
            }
    
            // get result if ready, otherwise block and wait
            try {
                return f.get();
            } catch (CancellationException e) {
                cache.remove(arg, f);
            } catch (ExecutionException e) {
                throw LaunderThrowable.launderThrowable(e.getCause());
            }
        }
      }
    }
    

     类似资料:
    • 问题内容: 在将此问题标记为重复之前,请仔细阅读问题。 以下是伪代码的代码段。我的问题是-下面的代码是否不会破坏并行异步处理的概念? 我之所以这样问,是因为在下面的代码中,主线程会提交要在其他线程中执行的任务。在队列中提交任务后,它将阻塞Future.get()方法,以使任务返回值。我宁愿在主线程中执行任务,而不是提交到其他线程并等待结果。通过在新线程中执行任务可以得到什么? 我知道您可以等待有限

    • 本文向大家介绍C#调用Python模块的方法,包括了C#调用Python模块的方法的使用技巧和注意事项,需要的朋友参考一下   当下,C#与Python都是比较热门的计算机编程语言,他们各有优缺点,如果能让他们互相配合工作,那是多么美好的事情,今天我来讲解一下如何利用C#来调用Python。   如果让C#支持调用Python模块,我们首先需要安装一些扩展,这里推荐使用IronPython库。 第

    • 本文向大家介绍调用下面的方法,得到的返回值是什么?相关面试题,主要包含被问及调用下面的方法,得到的返回值是什么?时的应答技巧和注意事项,需要的朋友参考一下 代码走到第3行的时候遇到了一个MathException,这时第4行的代码就不会执行了,代码直接跳转到catch语句中,走到第 6 行的时候,异常机制有一个原则:如果在catch中遇到了return或者异常等能使该函数终止的话那么有finall

    • 我有一个这样的测试 lucene6中的在这里...从中可以链接到超类并查看是(非)。