Futuretask不起作用

时间:2014-11-12 20:51:56

标签: java multithreading concurrency

我以类似于Brian Goetz的书Java Concurrency in Practice中提供的内容创建了FutureTask(可以找到代码示例here,列出5.12 })。

问题是,即使给定10秒,任务也会超时。该任务只返回true,因此不应该是它发生的原因:

public static void main(String[] args) throws Exception {

    FutureTask<Boolean> task = new FutureTask<>(new Callable<Boolean>() {
        @Override
        public Boolean call() throws Exception {
            return true;
        }
    });

    System.out.println(task.get(10, TimeUnit.SECONDS));
}

此代码打印:

Exception in thread "main" java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask.get(Unknown Source)
    at Main.main(Main.java:19)

2 个答案:

答案 0 :(得分:6)

您还没有执行任务。永远不会有结果。 javadoc

  

此类提供Future的基本实现,以及方法   开始并取消计算,查询是否有计算   完成,检索计算结果结果可以   仅在计算完成时检索

将任务提交到ExecutorService以异步运行。

Executors.newSingleThreadExecutor().submit(task); // ideally shutdown the ExecutorService afterwards

或同步运行

task.run();

在您提供的链接中,我假设在尝试获取结果之前调用了在新start()中运行FutureTask的{​​{1}}方法

答案 1 :(得分:0)

当您应用代码task.get(10, TimeUnit.SECONDS);时,FutureTask的状态永远不会更改,最后会抛出TimeoutException

您可能会在java.util.concurrent.FutureTask的源代码中看到它 (参见openjdk source http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/FutureTask.java#FutureTask.get%28%29):

public V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException {
    return sync.innerGet(unit.toNanos(timeout));
}

// In inner class java.util.concurrent.FutureTask.Sync (extends java.util.concurrent.locks.AbstractQueuedSynchronize)
// and in java.util.concurrent.locks.AbstractQueuedSynchronize:
innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
    if (!tryAcquireSharedNanos(0, nanosTimeout))
        throw new TimeoutException();
    if (getState() == CANCELLED)
        throw new CancellationException();
    if (exception != null)
        throw new ExecutionException(exception);

    return result;
}

public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    return tryAcquireShared(arg) >= 0 ||
        doAcquireSharedNanos(arg, nanosTimeout);
}

protected int tryAcquireShared(int ignore) {
    return innerIsDone() ? 1 : -1;
}

boolean innerIsDone() {
    return ranOrCancelled(getState()) && runner == null;
}

private boolean ranOrCancelled(int state) {
    return (state & (RAN | CANCELLED)) != 0;
}
// I know it's difficult :|
private void doAcquireShared(int arg) {
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head) {
                int r = tryAcquireShared(arg);
                if (r >= 0) {
                    setHeadAndPropagate(node, r);
                    p.next = null; // help GC
                    if (interrupted) selfInterrupt();
                    failed = false;
                    return;
                }
            }
            if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed) cancelAcquire(node);
    }
}

抱歉我的英文。