我正在学习 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);
}
最佳答案
run
对比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);
https://stackoverflow.com/questions/66588952/