如果在空检查后发生关闭,是否复制引用以避免 NPE?

Copy reference to avoid NPE if close happens after null check?

这是commons-dbcp2的源码,为什么能避免NPE?

public int getNumActive() {
    // Copy reference to avoid NPE if close happens after null check
    GenericObjectPool<PoolableConnection> pool = connectionPool;
    if (pool != null) {
        return pool.getNumActive();
    }
    return 0;
}

注意变量 connectionPool 被复制到一个新变量 pool 中。这种复制引用和使用新引用的模式用于多线程*和原始变量 (connectionPool) 被不同线程 overwritten/cleared 的机会。

在这种情况下,如果有两个线程,一个调用 close 方法,另一个调用 getNumActive 方法,那么有可能第一个 close 方法清除 connectionPool 变量,然后 getNumActive 方法尝试运行。

如果发生这种情况,即使原始变量被清除,它的副本 (pool) 仍然存在。所以 pool.getNumActive(); 永远不会导致 NPE

*用词很草率