java.util.concurrent.Future.get() 不返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2585971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:31:29  来源:igfitidea点击:

java.util.concurrent.Future.get() not returning

javaconcurrencymultithreadingfutureexecutorservice

提问by Paul Reiners

I have the following Java code:

我有以下 Java 代码:

final Future future = exeService.submit(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);

future.get();

where exeServiceis an instance of

哪里exeService是一个实例

java.util.concurrent.ExecutorService

The problem is that myObject.doSomething()never returns, and, hence, future.get()never returns.

问题是myObject.doSomething()永远不会回来,因此future.get()永远不会回来。

However, if I replace the call to submitwith a call to executelike this:

但是,如果我将调用替换submitexecute这样的调用:

exeService.execute(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);

the call to myObject.doSomething()does return. I don't know if it matters, but doSomething()is a voidmethod.

调用myObject.doSomething()确实返回。我不知道这是否重要,但它doSomething()是一种void方法。

Why is doSomething()finishing when using executebut not when using submit?

为什么doSomething()使用execute时完成而使用时不完成submit

Also, I don't need to use Future.get(); that just seemed to be the most natural way of doing this. (I also run into the same problem with CountdownLatch.) The point is that I need to wait for doSomething()to finish before proceeding, and, for complicated reasons I won't go into here, I need to launch it on a separate thread. If there is another way of doing this that works, that would be fine.

另外,我不需要使用Future.get(); 这似乎是最自然的方式。(我也遇到了同样的问题CountdownLatch。)重点是我需要等待doSomething()完成才能继续,而且由于复杂的原因我不会在这里讨论,我需要在单独的线程上启动它。如果有另一种可行的方法,那就没问题了。

采纳答案by pajton

As in Executor.execute() Javadoc:

Executor.execute() Javadoc 中

Executes the given command at some time in the future. The command may execute in a new thread, in a pooled thread, or in the calling thread, at the discretion of the Executor implementation.

在将来的某个时间执行给定的命令。根据 Executor 实现的判断,该命令可以在新线程、池线程或调用线程中执行。

So, the method execute()returns immediately leaving you with no option to query to status of submitted task.

因此,该方法会execute()立即返回,让您无法查询已提交任务的状态。

On the other hand ExecutorService.submit():

另一方面ExecutorService.submit()

Submits a Runnable task for execution and returns a Future representing that task. The Future's get method will return null upon successful completion.

提交一个 Runnable 任务以供执行,并返回一个代表该任务的 Future。Future 的 get 方法将在成功完成后返回 null。

The Future.get()will return onlyafter successful competion, so neverin your case.

的Future.get()将返回唯一成功赛区之后,所以从来没有在您的案件。

This is further noted in Future.get() documentation:

这在Future.get() 文档中有进一步说明:

Waits if necessary for the computation to complete, and then retrieves its result.

如有必要,等待计算完成,然后检索其结果。

回答by BalusC

I created an SSCCE:

我创建了一个SSCCE

package com.stackoverflow.q2585971;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test {

    public static void main(String args[]) throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<?> future = executor.submit(
            new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("Epic fail.");
                    }
                }
            }
        );

        System.out.println("Waiting for task to finish..");
        future.get();
        System.out.println("Task finished!");
        executor.shutdown();
    }

}

It works perfectly fine. It first prints

它工作得很好。它首先打印

Waiting for task to finish..

then after one second you see

然后一秒钟后你看到

Task finished!

So, your problem lies somewhere else. I'll duplicate my comment on your question here:

所以,你的问题出在其他地方。我会在这里重复我对你的问题的评论:

Your question is pretty confusing. The first construct should just work. The confusion is in "returning". Don't you just mean "finishing" or "executing"? Your confusion seems to be based on the fact that future.get()actually waits for the runnable to be finished and thus will block the thread and prevent it from executing the remnant of the code after the future.get()line.

你的问题相当混乱。第一个构造应该可以正常工作。混淆在于“返回”。你的意思不就是“完成”或“执行”吗?您的困惑似乎是基于这样一个事实,即future.get()实际等待可运行完成,因此会阻塞线程并阻止它执行该future.get()行之后的代码的剩余部分。

回答by Alexander Pogrebnyak

Check for a deadlock(s) in doSomething.

检查 中的死锁doSomething

I would start with searching for waitcalls.

我会从搜索wait电话开始。

If you waitfor something, you need to signal the object you are waiting for from the other thread by calling notifyor notifyAll.

如果您wait需要某些东西,您需要通过调用notify或来向其他线程发送您正在等待的对象的信号notifyAll

回答by anish

Java futures are blocking! get(). This method blocks the current thread until a future instance completes its work, thus requiring the use of one thread more than the work that must be performed just to manage what happens when it is done

Java 期货受阻了! get(). This method blocks the current thread until a future instance completes its work, thus requiring the use of one thread more than the work that must be performed just to manage what happens when it is done