如何解决FutureTask get vs run,任务永远不会完成
我正在学习 Callables 并决定制作一个非常简单的程序。问题是当我调用 getFutureTask(); 时线程被阻塞了; Thread.State: TIMED_WAITING(在对象监视器上)
当我在 futureTask.get() 之前编写 futureTask.run() 时,你能告诉我为什么会这样吗? 我明白 get() 方法等待并返回结果。但无法理解 run() 方法的作用。 我非常感谢您的回答!
public static void main(String[] args) throws ExecutionException,InterruptedException,TimeoutException {
FutureTask futureTask = getFutureTask(1);
System.out.println(futureTask.get());
}
public static FutureTask<Integer> getFutureTask(Integer i) {
return new FutureTask<Integer>(() -> i*45);
}
解决方法
来自 FutureTask
的 API:
get() - 必要时等待计算完成,然后 检索其结果。
run() - 将此 Future 设置为其计算结果,除非它 已取消。
因此,run()
将实际运行您的 FutureTask 并最终得出计算结果。 get()
另一方面给你结果,如果计算完成。 但是它不会开始计算,也不会调用 run()
本身。
另见@Zabuzard 的评论:
run 是实际开始执行任务的方法。这是 应该在不同的线程中调用,例如由 执行者服务。 get 不会触发执行,它只是等到 任务完成,这发生在 run() 的末尾。 FutureTask 不是 真的应该由用户直接使用。相反,你应该 查看 ExecutorService 和 CompletableFuture 以获得漂亮的界面 产生异步任务。
,
run
vs get
run
是实际开始执行任务的方法。它应该在不同的线程中调用,例如由 ExecutorService
调用。
get
将不触发执行,它只是等到任务完成,即直到 run
完成。这显然意味着您以某种方式在不同线程之前或从不同线程调用 run
。
ExecutorService
和 CompletableFuture
FutureTask
实际上不应该由用户直接使用。它更多是在幕后使用的类类型,以实现一个很好的异步 API。更具体地说,它是 Future
的基本实现,例如当您使用它生成任务时由 ExecutorService
返回。
相反,您应该查看 ExecutorService
ExecutorService service = Executors.newCachedThreadPool();
...
Future<Integer> task = service.submit(() -> i * 45);
...
Integer result = task.get();
和CompletableFuture
CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> i * 45);
...
Integer result = task.get();
一个易于使用的界面来生成异步任务。
CompletableFuture
的优点是您还可以设置一个操作管道,一旦前一个操作完成,这些操作将全部异步执行。例如:
CompletableFuture<Void> task = CompletableFuture.supplyAsync(Foo::readSomeFile)
.thenApplyAsync(Foo::validateData)
.thenApplyAsync(Foo::compressData)
.thenAcceptAsync(Foo::uploadData);
,
你的函数 () -> i*45
只是一个可调用的。除非您真正开始执行,否则它不会真正执行。
而这正是 run()
的用途。
因此,除非您没有明确启动线程,否则不会调用 FutureTask 的任何内容。
而 get()
旨在等待线程完成。
因此,通常情况下,您正在启动一项任务(使用 run()
),执行其他一些操作,然后使用 get()
获得结果,或者如果任务花费的时间比预期的要长,则在那里等待。
你可以检查一下,例如通过运行一些 System.out:
public static FutureTask<Integer> getFutureTask(Integer i) {
return new FutureTask<Integer>(() -> {
System.out.println("Task started");
return i * 45;
});
}
你什么都看不到
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。