简体   繁体   English

为什么这个 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");

We submit Callable to Executor with 2 threads, but when i tell m.calculate(5).get() it block main thread.我们使用 2 个线程将 Callable 提交给 Executor,但是当我告诉m.calculate(5).get()它阻塞主线程。 So, I can't understand, when and why should I use Future if it blocks the main thread and doesn't run asynchronously?所以,我不明白,如果Future阻塞主线程并且不异步运行,我什么时候以及为什么应该使用它?

If you look into the documentation of Future::get it says: " Waits if necessary for the computation to complete, and then retrieves its result. " By calling this method you agree to wait for the result in the main thread.如果您查看Future::get的文档,它会说:“如果计算完成,则等待,然后检索其结果。 ”通过调用此方法,您同意在主线程中等待结果。

You can check if Future has completed by calling Future::isDone , which returns boolean.您可以通过调用Future::isDone来检查 Future 是否已完成,它返回布尔值。

In your scenario it can be used like this在您的场景中,它可以像这样使用

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();

See: doc见: 文档

Future is indeed a very limited abstraction, in more realistic cases you should use CompletableFuture instead. Future确实是一个非常有限的抽象,在更现实的情况下,您应该使用CompletableFuture代替。 Future is a pretty old class (since java 1.5 I guess) so the understanding of the industry has gradually evolved in the field of concurrent programming, Future是一个相当古老的类(我猜从 java 1.5 开始)所以业界对并发编程领域的理解逐渐演变,

Nevertheless, it can still be useful by itself.尽管如此,它本身仍然很有用。

What if instead of spawning one future and immediately calling get on it, we would like to spawn many tasks and store the result in some list:如果不是生成一个 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM