为什么此方法与阻塞同步运行?

问题描述 投票:0回答:2
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如果它阻塞了主线程并且没有异步运行?

java future
2个回答
3
投票

如果查看Future ::: get的文档,其内容为:“ 等待计算完成,然后检索其结果。”通过调用此方法,您同意在主机中等待结果线。

您可以通过调用Future :: isDone,返回boolean来检查Future是否已完成。

在您的情况下,可以像这样使用

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


2
投票

Future确实是一个非常有限的抽象,在更实际的情况下,您应该使用CompletableFutureFuture是一个非常老的类(我猜是从Java 1.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
}
© www.soinside.com 2019 - 2024. All rights reserved.