我以类似于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)
答案 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);
}
}
抱歉我的英文。