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

FutureTask是如何进行异步计算的

曹经业
2023-03-14
new Thread(new Runnable() {
           public void run() {
                 .............
                 .............
                 .............
    }
}).start();

如果我在main中这样做,它将创建一个新线程,并将向其提交一个任务以进行异步计算。

如果您看到FutureTask文档,它还会说:

可取消的异步计算。此类提供了Future的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法。

那么,FutureTask是如何进行异步计算的呢?它是否在内部创建线程,并提交我们在实例化FutureTask时给它的任务,比如:

FutureTask f = new FutureTask(new MyCallable());

否则它不可能是异步计算,请向我提供它将任务提交给线程的FutureTask源代码中的代码片段,使其成为异步计算。谢谢。

我得到了答案。它基本上是尝试在与调用者相同的线程中运行任务。这在给定的代码中非常明显:

当您调用futureTask时。run()它只调用sync。innerRun()和sync是内部类sync的实例。因为它只调用同一线程中的可调用对象。

void innerRun() {
        if (!compareAndSetState(READY, RUNNING))
            return;

        runner = Thread.currentThread(); //here it is getting the current thread
        if (getState() == RUNNING) { 
            V result;
            try {
                result = callable.call();//here calling call which executes in the caller thread.
            } catch (Throwable ex) {
                setException(ex);
                return;
            }
            set(result);
        } else {
            releaseShared(0); // cancel
        }
    }

共有1个答案

党源
2023-03-14

那么FutureTask是如何进行异步计算的呢?它是否在内部创建线程,并在实例化FutureTask时提交我们给它的任务,比如:

未来任务(FutureTask)不是为用户直接使用而设计的。它旨在通过ExecutorService接口和实现它的类来使用。正是那些使用FutureTask和fork线程等的类。您可能需要阅读有关如何使用ExecutorService并发类的更多信息。

ThreadPoolExecutor类是实际管理池中线程的主要类。通常,您调用执行器。newCachedThreadPool()或执行器。newFixedThreadPool(10),以获取其实例。

// create a thread pool with 10 workers
ExecutorService threadPool = Executors.newFixedThreadPool(10);
// define your jobs somehow
for (MyCallable job : jobsToDo) {
    // under the covers this creates a FutureTask instance
    Future future = threadPool.submit(job);
    // save the future if necessary in a collection or something
}
// once we have submitted all jobs to the thread pool, it should be shutdown
threadPool.shutdown();
// now we can go back and call `future.get()` to get the results from our jobs

从学术角度来看,TPE在封面下扩展了AbstractExecutorService,您可以在那里看到用于管理线程池中任务的FutureTask类:

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}
...
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
    return new FutureTask<T>(callable);
}

TPE内部的代码相当复杂,要显示html" target="_blank">执行异步调用的“片段”并不容易。TPE查看是否需要向池中添加更多线程。将其提交到任务队列,该队列可以拒绝或接受该任务,然后线程将该任务出列并在后台运行。

 类似资料:
  • MXNet使用异步计算来提升计算性能。理解它的工作原理既有助于开发更高效的程序,又有助于在内存资源有限的情况下主动降低计算性能从而减小内存开销。我们先导入本节中实验需要的包或模块。 from mxnet import autograd, gluon, nd from mxnet.gluon import loss as gloss, nn import os import subproces

  • 问题内容: 我有一个singleThreadExecutor以便以串行顺序执行提交给它的任务,即一个任务接一个,没有并行执行。 我有可运行的东西,像这样 } 例如,当我向上述单线程执行器提交MyRunnable的三个实例时,我希望执行第一个任务,并且由于Thread.sleep在TIMED_WAITING中具有其执行线程(我可能对特定的线程有误州)。其他两个任务不应分配有执行它们的线程,至少直到第

  • 问题内容: 最近,我一直在玩 TensorFlow, 并提到该框架无法使用我所有可用的计算资源。在卷积神经网络教程中,他们提到 天真地采用模型参数的异步更新会导致次优的训练性能,因为单个模型副本可能会在模型参数的陈旧副本上进行训练。相反,采用完全同步更新将与最慢的模型副本一样慢。 尽管他们在教程和白皮书中都提到了这一点,但我并没有真正找到在本地计算机上进行异步并行计算的方法。可能吗 还是它是Ten

  • 问题内容: 我有一个对象,该对象带有一种方法,希望以类似以下方式向库客户端(尤其是脚本客户端)公开: 但是我可以使用的原始“东西”是一组事件驱动的类: 在其中,ImplementingThing接受输入,执行一些不可思议的工作,例如将任务排队入队列,然后稍后在发生结果时,在可能与调用ImplementingThing.doSomethingAsync()相同的线程上调用该线程。 有没有一种方法可以

  • 问题内容: 发现在Java 1.6(以及从Eclipse)上运行时,吞没了该方法中的异常之后,我试图找到一种捕获这些异常的方法,而不会在我的所有实现中都添加throw / catch 。 该API建议覆盖应对此有所帮助: 导致此future报告一个ExecutionException,并以给定throwable作为其原因,除非已经设置或取消了此Future。计算失败时,run方法在内部调用此方法。

  • 让我们假设有一个服务器,当收到一个汽车模型的请求时,它会查询所有已知的汽车经销商,寻找最便宜的汽车,并回复价格(使用任何协议)。这个动作需要一段时间。在一个临时的阻塞请求/响应服务器模型中,我这样做了 我不想阻塞我的客户机主线程20秒,所以我宁愿异步执行它。我对异步的理解是,我可以将某种对象传递给它,并在工作中携带一个对象。一旦服务器准备好响应,它将通知我传递的对象- 这种方法需要库匹配——客户端