为什么这个未来的方法会阻塞主线程?

pepwfjgg  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(397)
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");

我们用两个线程将callable提交给executor,但是当我告诉 m.calculate(5).get() 它阻塞了主线程。所以,我不明白,什么时候用,为什么用 Future 如果它阻塞了主线程并且没有异步运行?

qojgxg4l

qojgxg4l1#

Future 确实是一个非常有限的抽象,在更实际的情况下你应该使用 CompletableFuture 相反。 Future 是一个非常古老的类(我猜是从Java1.5开始的),所以对这个行业的理解在并发编程领域逐渐发展,
然而,它本身仍然是有用的。
如果不是孕育一个未来并立即召唤 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
}
ulydmbyx

ulydmbyx2#

如果你查一下 Future::get 它说:“如果需要,等待计算完成,然后检索其结果。”通过调用此方法,您同意在主线程中等待结果。
你可以打电话检查未来是否已经完成 Future::isDone ,返回布尔值。
在您的场景中,它可以这样使用

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

相关问题