jdbc - 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?</p>
解决方案
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");
}
推荐阅读
- javascript - JavaScript 是否有一个对象文字速记,它会自动为属性分配一个值,该值是属性名称的字符串?
- excel - 如何用已知值之间的线性级数填充空白列
- gem5 - gem5中如何指定预取策略和替换策略?
- boolean - 如何在 smali 中设置布尔值为真
- php - Laravel PackageManifest.php 第 131 行:未定义索引:名称
- r - 我们谈论 R 中的引用类型和原始类型吗?
- python - Discord.py:发送消息时如何在 args 中保留 \n
- ios - 在 SpriteKit 游戏中处理不同的屏幕尺寸
- javascript - 传递参数时,未定义不是反应本机的对象(评估'_this.props.navigation')
- python-3.x - Discord.Py 根据反应发送消息