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

简单的CompletableFuture。SupplySync()导致IllegalMonitorStateException错误

白淇
2023-03-14

我正在java8中尝试:

  public static void main(String[] args) throws Exception {
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(
      () -> { return 911; });
    future.whenComplete(
      (result, error) -> {
        System.out.println("Alarm:" + result);
        error.printStackTrace();
      }
    );
    future.wait();
  }

运行时,我得到以下输出:

Alarm:911
[WARNING]
java.lang.IllegalMonitorStateException
    at java.lang.Object.wait (Native Method)
    at java.lang.Object.wait (Object.java:502)
    at mygroup.UseCompletableFuture.main (UseCompletableFuture.java:15)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:254)
    at java.lang.Thread.run (Thread.java:748)

是否需要“错误”信息?我的代码片段中有没有遗漏什么?

共有2个答案

景元忠
2023-03-14

显示堆栈跟踪的异常由future引发。wait(),与第二个CompletableFuture的错误参数无关。之所以发生这种情况,是因为调用它的线程需要持有对象的监视器。有关线程成为对象监视器所有者的含义的描述,请参见本文。您的代码基本上必须在同步块中才能调用wait()或notify()。您可能打算调用get()wait()/notify()方法是对象继承的通用同步方法,自Java诞生以来就一直存在。

至于错误参数,它实际上是空的,因为第一阶段正常完成。因此,该行出现错误。printStackTrace()应该抛出一个NPE。然而,您的代码根本无法处理。它被抛出到执行stage的异步线程中,并保持静默。请参阅与此行为相关的帖子。

我怀疑您想在未来调用get()方法。首先,您应该将第二阶段分配给一个变量(Future仍在引用第一阶段):

future = future.whenComplete(
      (result, error) -> {
        System.out.println("Alarm:" + result);
        System.out.println(error);
        error.printStackTrace();
      }
);

然后可以对其调用get(),这允许您处理ExecutionException,它将包装第二阶段发生的NPE:

try {
    result = future.get();
    System.out.println(result);
} catch (InterruptedException e) {
    ...
} catch (ExecutionException e) {
    ...
}
傅玮
2023-03-14

etc方法派生自Object类。如果需要使用它,则需要监控对象。

在您的情况下,您不需要监视,但需要“等待可完成的未来完成”。在这种情况下,您需要从等待切换到获取方法。

 类似资料:
  • 需要确认一些事情。以下代码: 将与以下相同: 右? 此外,接下来的另外两个问题是“我们有什么理由使用 ? 1) 有转换的大代码吗? 或 2)需要在其他地方重用lambda块?

  • 要并行或异步运行一些东西,我可以使用ExecutorService:

  • 问题内容: 这个程序 这样死 我觉得这很令人困惑。为什么它不起作用,我是否有错?如果是这样,我该怎么做?除非我掩盖了某些内容,否则根据em-synchrony自述文件,这是洁食。 问题答案: 我认为,如果您找到正确的em-hiredis版本并尝试猴子补丁,那么您的代码就可以工作,这是依赖项松散的问题之一。 这是一个完全正常的代码,但是基于em-synchrony的master分支: 宝石文件: t

  • 问题内容: 由于某些原因,我的fx:id无法正确绑定到我的类,因此始终会导致错误。 控制者 XML文件 我认为我了解问题的根源,但不了解如何正确解决。根据这个问题的答案,我认为我正在尝试在调用构造函数之前分配FXML元素(并且这些元素只能在初始化期间/之后分配)。 有没有办法 不 执行此操作?还是我犯了一个完全不同的错误? 问题答案: 您使用进口 在您的fxml文件中。 因此,在加载fxml文件时

  • 启用proguard规则后,我在向网络发送任何内容之前遇到以下错误。 java.lang.RuntimeException:无法将FormDocTankPermission转换为RequestBody 引起的 com.fasterxml.jackson.databind.exc.InvalidDefinitionException:找不到类FormDocTankPermission的序列化程序,也

  • 我想我明白我的问题的根源,但我不明白如何正确地解决它。根据这个问题的答案,我认为我试图在调用构造函数之前分配FXML元素(这些元素只能在初始化期间/之后分配)。 有没有一种方法可以在不实现的情况下做到这一点?还是我犯了一个完全不同的错误?