为什么这个 Future 的方法会阻塞主线程?
Why this Future's method is blocking main thread?
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> calculate(Integer input) {
return executor.submit(() -> {
Thread.sleep(3000);
return input * input;
});
}
public static void main(String []args) throws Exception {
Main m = new Main();
System.out.println(m.calculate(5).get());
System.out.println("Main");
我们使用 2 个线程将 Callable 提交给 Executor,但是当我告诉 m.calculate(5).get()
它会阻塞主线程。
所以,我不明白,如果它阻塞主线程并且不异步 运行,我什么时候以及为什么应该使用 Future
?
如果您查看 Future::get
的文档,它说:“如有必要,等待计算完成,然后检索其结果。”通过调用此您同意在主线程中等待结果的方法。
您可以通过调用 Future::isDone
来检查 Future 是否已完成,returns 布尔值。
在你的场景中可以这样使用
public static void main(String []args) throws Exception {
Main m = new Main();
Future<Integer> futureInt = m.calculate(5);
// do some other asynchronous task or something in main thread while futureInt is doing its calculations
// and then call Future::get
int result = futureInt.get();
参见:doc
Future
确实是一个非常有限的抽象,在更实际的情况下,您应该使用 CompletableFuture
代替。 Future
是一个相当老的 class(我猜是从 java 1.5 开始的)所以业界的理解在并发编程领域逐渐发展,
尽管如此,它本身还是很有用的。
如果我们不生成一个 future 并立即调用 get
,我们想生成许多任务并将结果存储在某个列表中会怎么样:
List<Future<Integer>> futures = new ArrayList<>(10);
for(int i = 0 ; i< 10; i++) {
futures.add(calculate(<some_integer>));
}
// at this point all futures are running concurrently
for(int i = 0 ; i < 10; i++) {
futures.get(i).get(); // will either return immediately or we'll block the main thread but the point is that all the calculations will run concurrently
}
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> calculate(Integer input) {
return executor.submit(() -> {
Thread.sleep(3000);
return input * input;
});
}
public static void main(String []args) throws Exception {
Main m = new Main();
System.out.println(m.calculate(5).get());
System.out.println("Main");
我们使用 2 个线程将 Callable 提交给 Executor,但是当我告诉 m.calculate(5).get()
它会阻塞主线程。
所以,我不明白,如果它阻塞主线程并且不异步 运行,我什么时候以及为什么应该使用 Future
?
如果您查看 Future::get
的文档,它说:“如有必要,等待计算完成,然后检索其结果。”通过调用此您同意在主线程中等待结果的方法。
您可以通过调用 Future::isDone
来检查 Future 是否已完成,returns 布尔值。
在你的场景中可以这样使用
public static void main(String []args) throws Exception {
Main m = new Main();
Future<Integer> futureInt = m.calculate(5);
// do some other asynchronous task or something in main thread while futureInt is doing its calculations
// and then call Future::get
int result = futureInt.get();
参见:doc
Future
确实是一个非常有限的抽象,在更实际的情况下,您应该使用 CompletableFuture
代替。 Future
是一个相当老的 class(我猜是从 java 1.5 开始的)所以业界的理解在并发编程领域逐渐发展,
尽管如此,它本身还是很有用的。
如果我们不生成一个 future 并立即调用 get
,我们想生成许多任务并将结果存储在某个列表中会怎么样:
List<Future<Integer>> futures = new ArrayList<>(10);
for(int i = 0 ; i< 10; i++) {
futures.add(calculate(<some_integer>));
}
// at this point all futures are running concurrently
for(int i = 0 ; i < 10; i++) {
futures.get(i).get(); // will either return immediately or we'll block the main thread but the point is that all the calculations will run concurrently
}