6

我有以下 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()完成才能继续,并且由于复杂的原因我不会在这里讨论,我需要在单独的线程上启动它。如果有另一种可行的方法,那很好。

4

4 回答 4

18

Executor.execute() Javadoc中:

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

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

另一方面ExecutorService.submit()

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

Future.get ()只有在成功竞争后才会返回,所以永远不会在你的情况下。

Future.get() 文档中进一步指出了这一点:

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

于 2010-04-06T15:23:05.137 回答
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()行后代码的剩余部分。

于 2010-04-06T15:28:15.233 回答
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

于 2014-03-27T09:37:13.163 回答
0

检查 中是否存在死锁doSomething

我将从搜索wait电话开始。

如果您需要某些东西,您需要通过调用orwait来从另一个线程发出您正在等待的对象的信号。notifynotifyAll

于 2010-04-06T15:51:32.410 回答