
因此我们目前的线程栈信息上看,Spark 的 Thread ID:127 获取加载了mysql驱动并初始化DriverManager类,而DriverManager类初始化时会执行loadInitialDrivers(),并且这个方法会加载当前classPath下/META-INF/services/java.sql.Driver文件中的类(这个文件中包含有com.mysql.jdbc.Driver及其他驱动).
这时候 Thread ID 128 通过Druid连接池获取连接时,刚持有DriverManager类型的锁,
要等待Spark Thread ID:127 加载完DriverManager类,而 Thread ID:127 类又需要使用DriverManager类来加载driver class时,要等待 Thread ID 128 释放DriverManager类型锁,这样两个线程就互锁了。
解决的方法是让驱动类的加载过程变为单线程加载方式.在我们代码中调用Druid连接池获取Connection之前,串行执行
DriverRegistry.register("com.mysql.jdbc.Driver");
具体JDBC驱动类初始化死锁问题
可以参考 你假笨 的 JDK的sql设计不合理导致的驱动类初始化死锁问题
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-78776-2.html
没遇到黑天鹅时
小子