首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Futuretask不管用

Futuretask不管用
EN

Stack Overflow用户
提问于 2014-11-12 20:51:55
回答 2查看 4.9K关注 0票数 1

我以类似于Brian的“FutureTask Java并发在实践中的应用”(代码示例可以找到这里,清单5.12)的方式创建了一个5.12

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

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

此代码打印:

代码语言:javascript
复制
Exception in thread "main" java.util.concurrent.TimeoutException
    at java.util.concurrent.FutureTask.get(Unknown Source)
    at Main.main(Main.java:19)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-12 20:55:43

你还没完成任务。永远也不会有结果。javadoc

该类提供了Future的基本实现,并提供了启动和取消(计算)、查询以查看计算是否完成以及检索计算的结果的方法。只有在计算完成时才能检索结果

将任务提交给要异步运行的ExecutorService

代码语言:javascript
复制
Executors.newSingleThreadExecutor().submit(task); // ideally shutdown the ExecutorService afterwards

或者同步运行它。

代码语言:javascript
复制
task.run();

在您提供的链接中,我假设在尝试获得结果之前调用了在新的start()中运行FutureTaskFutureTask方法。

票数 6
EN

Stack Overflow用户

发布于 2014-11-12 22:04:10

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

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

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

对不起我的英语。

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

https://stackoverflow.com/questions/26896316

复制
相关文章

相似问题

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