Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
574 views
in Technique[技术] by (71.8m points)

driver - Why does jdbc DriverManager getConnection() need synchronized(DriverManager.class)?

ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
    // synchronize loading of the correct classloader.
    if (callerCL == null) {
        callerCL = Thread.currentThread().getContextClassLoader();
    }
}

I don't understand the comments, When will the correct classloader not be loaded?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It does not seem to serve a purpose, and this synchronized-block was removed in later Java versions. It is present in Java 8 update 275, but is not present in Java 11.0.9 (my guess is that it was removed in Java 9).

To me, it looks like a leftover from code that initialized a field instead of a local variable, or possibly it used to address other concurrency concerns. In Java 8, a number of (static) DriverManager methods (registerDriver and deregisterDriver) were defined as sychronized, so it is possible this served to establish a happens-before relation between those methods and the getConnection method. However, as driver registrations are stored in a CopyOnWriteArrayList, it would be unnecessary to establish such a happens-before relation; in older Java versions however, this likely was a plain ArrayList, so then it might have needed the happens-before.

However, I don't want to do code-archeology on older Java versions to confirm either of those theories.

So, in short: it is unnecessary and was removed in later Java versions.

Java 8 fragment:

//  Worker method called by the public getConnection() methods.
private static Connection getConnection(
    String url, java.util.Properties info, Class<?> caller) throws SQLException {
    /*
     * When callerCl is null, we should check the application's
     * (which is invoking this class indirectly)
     * classloader, so that the JDBC driver class outside rt.jar
     * can be loaded from here.
     */
    ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
    synchronized(DriverManager.class) {
        // synchronize loading of the correct classloader.
        if (callerCL == null) {
            callerCL = Thread.currentThread().getContextClassLoader();
        }
    }

    if(url == null) {
        throw new SQLException("The url cannot be null", "08001");
    }

Java 11 fragment

//  Worker method called by the public getConnection() methods.
private static Connection getConnection(
    String url, java.util.Properties info, Class<?> caller) throws SQLException {
    /*
     * When callerCl is null, we should check the application's
     * (which is invoking this class indirectly)
     * classloader, so that the JDBC driver class outside rt.jar
     * can be loaded from here.
     */
    ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
    if (callerCL == null || callerCL == ClassLoader.getPlatformClassLoader()) {
        callerCL = Thread.currentThread().getContextClassLoader();
    }

    if (url == null) {
        throw new SQLException("The url cannot be null", "08001");
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...