当前位置: 首页 > 知识库问答 >
问题:

Java未来:如何在执行Aysnc调用时解除主线程阻塞

程招
2023-03-14

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

但当我试图从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个答案

越伯寅
2023-03-14

如果需要在异步任务运行时在主线程中执行代码,则需要重新设计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();
}
常枫涟
2023-03-14

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

如果希望在任务完成后获得结果,请使用isDone()函数,如果任务完成(正常、异常等),该函数将返回true。然后调用get()

此外,您还可以使用get(长超时,时间单位)函数仅等待给定的时间段。在这种情况下,如果超时或任务已完成,主线程将自动“解锁”。

王庆
2023-03-14

未来的好处是能够在答案到来之前释放线程。所以我建议您使用未来的实现,比如CompletableFuture:

final ExecutorService executorService = Executors.newFixedThreadPool(10);

CompletableFuture.supplyAsync(() -> {
    try {
        return hystrixCommand.queue();
    } catch (Exception e) {
        return false;
    }
}, executorService);

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

 类似资料:
  • 问题内容: 根据我一直在阅读的定义: 线程基本上是并发(同时)运行的代码段 。 但是,如何在存在线程调度程序的情况下同时运行它们? 我读到,线程调度程序基本上是从线程池中随机选择一个线程在某个时刻运行。从中我得到一个确切的时间点,只有一个可运行线程真正处于运行状态(运行)。( 所有这些均来自SCJP Sun认证程序员学习指南 )有人可以澄清吗? 这些线程是否真正同时运行? 问题答案: 但是,如何在

  • 我试图用一个自定义对象创建一个新线程,然后从主线程调用这个自定义对象方法。其思想是,主线程可以继续执行其他任务,而自定义对象可以继续在第二个线程中工作: 输出为: 它应该更像这样: 所以主线程被阻塞,直到方法完成。主线程是否在第二个线程中等待完成(作为返回类型为空,我认为情况不会如此)?还是在第一个线程中执行,因此阻塞了它? 我知道使用下面的代码,我可以在另一个线程中执行,但它每次都会从头开始创建

  • 问题内容: 当使用and 对象时(提交任务时),如果我为将来的get函数指定一个超时值,则抛出a时基础线程会被杀死吗? 问题答案: 它不是。为什么会这样?除非你告诉。 例如,在有Callable的情况下,存在一个非常有效的担忧。如果您等待结果说20秒钟却没有得到结果,那么您对结果不再感兴趣。那时您应该完全取消任务。 像这样:

  • 本文向大家介绍iOS 在主线程上执行,包括了iOS 在主线程上执行的使用技巧和注意事项,需要的朋友参考一下 示例 当异步执行任务时,通常需要确保在主线程上运行一段代码。例如,您可能要异步访问REST API,但将结果放在屏幕上的UILabel中。在更新UILabel之前,必须确保您的代码在主线程上运行: 每当您更新屏幕上的视图时,请始终确保您正在主线程上执行此操作,否则可能会发生未定义的行为。

  • 问题内容: 我经历了这里列出的类似案例,但似乎没有用。 我使用MySQL Workbench与托管在另一台服务器上的数据库建立连接。尝试了几次,无法连接,然后出现此错误。我对我应该在哪里冲洗感到困惑。在PhpMyadmin下的SQL查询?Cos当我尝试输入以下命令时,它作为语法错误返回。我使用的是Windows操作系统,因此也没有输入我的外壳程序脚本。我现在正在通过Cpanel / phpmyad

  • 在我的用例中,我有一个带有Reactor Netty的Spring Webflux微服务,我有以下依赖项: null 由于(版本0.7.6版)已包含在最新的(版本2.0.1版)中,因此不能再使用:,请参阅->https://github.com/reactor/reactor-netty/issues/312 我的代码段: 这适用于版本2.0.0.release,但由于升级到版本2.0.1.rel