首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FutureTask是如何异步计算的

FutureTask是如何异步计算的
EN

Stack Overflow用户
提问于 2013-11-04 13:18:43
回答 1查看 5.7K关注 0票数 8
代码语言:javascript
复制
new Thread(new Runnable() {
           public void run() {
                 .............
                 .............
                 .............
    }
}).start();

如果我主要做到这一点,它将创建一个新线程,并将一个任务提交给它进行异步计算。

如果你看到FutureTask documentation,它也写着:

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

因此,asynchronous computation是如何在内部创建线程并提交我们在实例化FutureTask时赋予它的任务,比如:

代码语言:javascript
复制
FutureTask f = new FutureTask(new MyCallable());

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

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

当您调用futureTask.run()时,它只调用sync.innerRun();,而sync是内部类Sync的实例。因为它只对同一个线程中的可调用对象调用call()

代码语言:javascript
复制
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
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-04 13:20:45

因此,FutureTask是如何进行异步计算的,它是否在内部创建线程并提交我们在实例化FutureTask时赋予它的任务,例如:

FutureTask不是设计为用户直接使用的。它被设计为通过ExecutorService接口和实现它的类来使用。正是这些类使用了FutureTask和分叉线程等等。您可能需要阅读有关 concurrency classes的更多信息。

ThreadPoolExecutor类是实际管理池中线程的主要类。通常,您可以调用Executors.newCachedThreadPool()Executors.newFixedThreadPool(10)来获取它的实例。

代码语言:javascript
复制
// 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类用于管理线程池中的任务:

代码语言:javascript
复制
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内部的代码非常复杂,很难显示执行异步调用的“代码段”。TPE查看是否需要向池中添加更多线程。将其提交到可以拒绝或接受任务队列的任务队列中,然后线程将任务排出队列并在后台运行它们。

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

https://stackoverflow.com/questions/19768540

复制
相关文章

相似问题

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