Java中的同步和异步异常

时间:2018-07-17 07:36:32

标签: java

在阅读jvm specification时,我遇到了异常(2.10异常)

  

大多数异常是由操作人员同步执行的结果   它们发生的线程。相比之下,异步异常   可能在程序执行的任何时候发生……

两种类型有什么区别?

继续阅读,该规范给出了异步异常的示例

  

发生异步异常是因为:–类的stop方法   线程或线程组已被调用,或者–在内部发生错误   Java虚拟机实现。

但是在这方面,什么使类线程的stop方法特别?

您能否解释两者之间的区别,并给出一些示例,而不是给出的示例?

2 个答案:

答案 0 :(得分:1)

可以从另一个线程中调用stop方法,这可能会使被线程停止更改后的数据处于不一致状态。

因此,将删除Thread.stop()。我建议您不要使用它。

  

您能解释一下两者之间的区别,并给出一些例子吗?

区别在于,异步异常是由代码中任意位置的另一个线程触发的。

它们不应在正常操作下发生。

JVM的特定实现可能有其他错误,但没有详尽列表。 除了正常关闭之外,您无能为力。

答案 1 :(得分:1)

以下是显示两种异常类型的示例。考虑以下代码片段,这些代码片段显示了正在引发和处理的两种异常:

public static void main(String[] args) throws Exception {
    try {
        syncException();
    } catch (RuntimeException re) {
        System.out.println("-1-");
        re.printStackTrace();
    }

    CompletableFuture<Void> f = null;
    try {
        f = asyncException();
    } catch (RuntimeException ex) {
        System.out.println("-2-" + Thread.currentThread().getName());
        ex.printStackTrace();
    }

    try {
        f.get();
    } catch (Exception ex) {
        System.out.println("-3-");
        ex.printStackTrace();
    }
}

同步异常

private static void syncException() {
    throw new RuntimeException("Sync exception @" + Thread.currentThread().getName());
}

还有一个异步异常-在与调用代码不同的线程中引发:

private static CompletableFuture<Void> asyncException() {
    return CompletableFuture.runAsync(() -> {
        throw new RuntimeException("Async exception @" + Thread.currentThread().getName());
    }, Executors.newFixedThreadPool(1));
}

现在,执行该代码时,将生成以下堆栈跟踪:

同步异常的堆栈跟踪:

-1-
java.lang.RuntimeException: Sync exception @main
    at stackoverflow.Main.syncException(Main.java:34)
    at stackoverflow.Main.main(Main.java:11)

请注意,未打印-2-,因为该异常是异步的。有关如何处理异步异常的信息,请参见第三个catch块的堆栈跟踪。请注意,引发异常的线程与打印堆栈跟踪的线程不同:

-3-
java.util.concurrent.ExecutionException: java.lang.RuntimeException: Async exception @pool-1-thread-1
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
    at stackoverflow.Main.main(Main.java:26)
Caused by: java.lang.RuntimeException: Async exception @pool-1-thread-1
    at stackoverflow.Main.lambda$0(Main.java:39)
    at java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1626)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
  

相比之下,异步异常可能在程序执行的任何时候发生...

对此仅作评论:您会注意到,pool-1-thread-1线程执行时,线程main中的代码可能会引发异常。这可能是线程之间的相对关系。但是在这个示例中,main线程是主程序执行,我们可以说"Async exception @pool-1-thread-1"异常是异步发生的。