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

问题描述 投票:0回答:5

我有以下Java代码:

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

future.get();

其中

exeService

的实例
java.util.concurrent.ExecutorService

问题是

myObject.doSomething()
永远不会返回,因此,
future.get()
永远不会返回。

但是,如果我将对

submit
的调用替换为对
execute
的调用,如下所示:

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

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

为什么使用

doSomething()
execute
完成而使用
submit
时不完成?

另外,我不需要使用

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

java concurrency multithreading future executorservice
5个回答
18
投票

Executor.execute() Javadoc:

在某个时间执行给定的命令 未来的时间。该命令可以 在池中的新线程中执行 线程,或在调用线程中,位于 执行人的自由裁量权 实施。

因此,方法

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

另一方面ExecutorService.submit():

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

Future.get()将在成功竞争后返回only,所以在你的情况下never

这在

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

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


8
投票
我创建了一个

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(); } }

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

等待任务完成..

然后一秒钟后你就看到了

任务完成!

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

你的问题很令人困惑。第一个构造应该可以工作。困惑就在于“回归”。你不是指“完成”或“执行”吗?您的困惑似乎是基于以下事实:

future.get()

实际上等待可运行程序完成,因此会阻塞线程并阻止它执行
future.get()
行之后的剩余代码。


2
投票
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


    


0
投票
检查

doSomething

 中是否存在死锁。

我会从搜索

wait

 来电开始。

如果您

wait

 想要某件事,则需要通过调用 
notify
notifyAll
 来向其他线程发出正在等待的对象的信号。


0
投票
这里有很多问题:

  1. 当您执行 future.get() 时,此时它尚未执行完毕,因此不会返回任何内容。当它真正完成时,你永远不会回去询问结果。 所以 doSomething 确实会返回,但你永远不会再检查结果。

  2. doSomething 不返回任何内容也很重要。使用 future.get() 无需获取任何内容。

  3. 即使该方法返回了某些内容,它仍然会打印 null,因为该方法的结果会被忽略,因为您正在使用 runnable。您需要使用 callable 来保留方法的结果。

  4. 如果你真的需要等到得到结果才继续下一行,而不是在不知道计算是否完成的情况下执行 future.get,我们可以这样做

    Integer res = executorService.submit( myObject::doSomething ).get(); System.out.println(res); executorService.shutdown();
    
    
这里我假设 doSomething 返回一个 int。

执行 future.get 和上面的区别在于,在前一种方法中,您创建一个 future 对象并继续,然后尝试获取尚未准备好的结果。在这里,直到结果准备好并存储在 Integer 变量中之前,您不会继续前进。

© www.soinside.com 2019 - 2024. All rights reserved.