为什么throwable类的以下方法需要同步?

hgqdbh6s  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(436)
private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
private transient Object backtrace;

private synchronized StackTraceElement[] getOurStackTrace() {
    // Initialize stack trace field with information from
    // backtrace if this is the first call to this method
    if (stackTrace == UNASSIGNED_STACK ||
        (stackTrace == null && backtrace != null) /* Out of protocol state */) {
        int depth = getStackTraceDepth();
        stackTrace = new StackTraceElement[depth];
        for (int i=0; i < depth; i++)
            stackTrace[i] = getStackTraceElement(i);
    } else if (stackTrace == null) {
        return UNASSIGNED_STACK;
    }
    return stackTrace;
}

public synchronized Throwable fillInStackTrace() {
    if (stackTrace != null ||
        backtrace != null /* Out of protocol state */ ) {
        fillInStackTrace(0);
        stackTrace = UNASSIGNED_STACK;
    }
    return this;
}

public synchronized Throwable fillInStackTrace() {
    if (stackTrace != null ||
        backtrace != null /* Out of protocol state */ ) {
        fillInStackTrace(0);
        stackTrace = UNASSIGNED_STACK;
    }
    return this;
}

以上代码是jdk源代码
jdk公司version:1.8.0_144
异常堆栈不应该是线程私有的吗?为什么需要同步控制?

kokeuurv

kokeuurv1#

为什么下面的方法 Throwable 班级需要同步吗?
因为正常的原因。可能会有两个线程同时执行某个操作来触发这些调用中的任何一个。如果他们不是 synchronized 那可能会导致竞争状况或内存异常。
(请注意 stacktrace 或者 backtracevolatile 因此,如果代码是从多个线程测试和/或分配的,则有些线程可能会看到过时的值。)
现在,对所有可能的代码路径进行深入分析可能会发现,该代码在不声明这些方法的情况下是线程安全的 synchronized . 但如果是我写的代码,我可能会用 synchronized 无论如何,因为:
使用起来很安全 synchronized 这里,还有
相对于捕获异常的堆栈跟踪时发生的所有其他事情,互斥(可能是不必要的)的开销将很小,并且
例外情况应该很少发生。。。除非程序不正确地使用异常。
如果获取异常的stacktrace不是线程安全的,那么这是不可接受的。如果堆栈跟踪不可靠,那么调试java就完全是“废话”。在这种情况下,即使规范(javadoc)对此保持沉默,代码也必须是线程安全的。

相关问题