当前位置: 首页 > 面试题库 >

对Future.get()块的方法调用。这真的可取吗?

耿学义
2023-03-14
问题内容

在将此问题标记为重复之前,请仔细阅读问题。

以下是伪代码的代码段。我的问题是-下面的代码是否不会破坏并行异步处理的概念?

我之所以这样问,是因为在下面的代码中,主线程会提交要在其他线程中执行的任务。在队列中提交任务后,它将阻塞Future.get()方法,以使任务返回值。我宁愿在主线程中执行任务,而不是提交到其他线程并等待结果。通过在新线程中执行任务可以得到什么?

我知道您可以等待有限的时间等,但是如果我真的在乎结果怎么办?如果要执行多个任务,问题将变得更加严重。在我看来,我们只是同步进行工作。我知道Guava库提供了一个非阻塞侦听器接口。但是我很想知道我对Future.get()API的理解是否正确。如果是正确的,为什么将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());
}

问题答案:

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

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

您有两种选择:

  • 调用isDone(),如果结果准备就绪,可以通过调用来请求get(),请注意没有阻塞
  • 无限期封锁 get()
  • 指定超时时间 get(long timeout, TimeUnit unit)

整个Future API过程有一种简单的方法可以从执行并行任务的线程中获取值。如上面的项目符号所述,可以根据需要同步或异步完成此操作。

用CACHE示例更新

这是 Java Concurrency In Practice中的 一个缓存实现,是一个非常好的用例Future

  • 如果计算已经在运行,则对计算结果感兴趣的调用方将等待计算完成
  • 如果结果已在缓存中准备好,则调用者将收集它
  • 如果结果尚未准备好并且尚未开始计算,则调用方将开始计算并将结果包装在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()方法返回值。我宁愿让任务在主线程中执行,而不是提交到另一个线程并等待结果。通过在新线程中执行任务,我得到了什么? 我知道你可以等一段有限的时间等等,但是如

  • 使用或,是否有任何方法可以拦截对对象的非静态方法的调用,或者至少是对单例对象的非静态方法的调用? 以下类提供了一个示例: 但是,上面的类只提供了一个私有构造函数,因此不能对其进行扩展。使用返回部分模拟(spy)也不会起作用,因为类不提供无参数构造函数。 想要的嘲弄能以其他任何方式实现吗?对于非单例类可以这样做吗?

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

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

  • 我尝试通过使用ThreadPoolExecutor调用在单独线程中执行DNS查询的所有例程来实现异步DNS解析器。 我对可调用对象的定义如下: 基本上,可调用对象将尝试将主机名解析为InetAddress。 然后我定义一个ExecutorService: 我提交了可调用任务: 然后我看着我的程序抛出的日志,它们很奇怪。这是我在解决DNS中有一个超时: 因此,在提交我的可调用对象之后,但在调用fut

  • 本文向大家介绍asp.net获取真实ip的方法,包括了asp.net获取真实ip的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了asp.net获取真实ip的方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的asp.net程序设计有所帮助。