Java Future:如何在执行Aysnc调用时取消阻塞主线程

时间:2019-04-11 09:14:46

标签: java concurrency java-8 future completable-future

当我使用ExecutorService进行异步调用时,它将返回Future Object。根据返回的布尔值,我必须记录异步调用的状态。

但是当我尝试从Future对象调用方法get方法时,它会阻塞主线程的执行。

是否可以取消阻止主线程的执行?

public class FutureExample {

    static HystrixCommand<Boolean> hystrixCommand;

    public FutureExample(HystrixCommand<Boolean> hystrixCommand){
        FutureExample.hystrixCommand = hystrixCommand;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {


        Boolean something = asyncCall();

        if(something) {
            System.out.println("Future task is done");
        }

        System.out.println("Don't wait for async call");

    }

    private static Boolean asyncCall() throws InterruptedException, ExecutionException {

        Future<Boolean> response = hystrixCommand.queue(); // Aysnc Call to remote server

        return response.get(); //this is blocking main thread
    }

}

3 个答案:

答案 0 :(得分:4)

关于期货的好处是能够释放线程,直到答案到来为止。 因此,我建议您使用Future实现,例如CompletableFuture:

android:configChanges="orientation"
android:screenOrientation="portrait"

这将在另一个线程上工作,并且当该将来结束时,它将完成。

答案 1 :(得分:1)

根据JavaDocsget()方法在必要时等待计算完成,然后检索其结果。

如果您想在任务完成后获得结果,请使用isDone()函数,如果任务完成(正常,异常情况等),它将返回true。然后调用get()

此外,您可以使用get(long timeout, TimeUnit unit)函数仅等待给定的时间。在这种情况下,如果超时或任务已完成,主线程将自动“解除阻止”。

答案 2 :(得分:1)

如果您需要在异步任务运行时在主线程中执行代码,则需要重新设计asyncCall方法以使其返回将来。

一个例子:

private static Future<Boolean> asyncCall() 
      throws InterruptedException, ExecutionException {

    return hystrixCommand.queue(); 
}

这样,main方法就进行有关何时阻止/等待的调用:

public static void main(String[] args) 
     throws InterruptedException, ExecutionException {

    Future<Boolean> something = asyncCall();

    //do something while async call is running

    //to check whether it's done running:
    if(something.isDone()) {
        System.out.println("Future task is done");
    }

    //when you're finally ready to wait:
    System.out.println("Waiting for async call to finish");
    Boolean result = something.get();
}