[讨论] Class.forName()被阻塞

red_xie 2013-12-26

问题描述:

两个线程,一个线程加载加载Mysql驱动,一个加载Oracle驱动,然后被阻塞在Class.forName()

Main:

 

public class ClassThread {

	public static void main(String[] args) {
		InnerMysqlThread it1 = new InnerMysqlThread();
		InnerOracleThread it2 = new InnerOracleThread();
		it1.start();
		it2.start();
	}
}

 加载Mysql:

 

 

public class InnerMysqlThread extends Thread {

	@Override
	public void run() {
		try {
			Class.forName("com.mysql.jdbc.Driver", true, this.getClass().getClassLoader());
			System.out.println("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

}

 

 

加载Oracle:

 

public class InnerOracleThread extends Thread {

	@Override
	public void run() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver", true, this.getClass().getClassLoader());
			System.out.println("oracle.jdbc.driver.OracleDriver");
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

 

 

一直阻塞在java.sql.DriverManager中

 

线程dump为:

 

"Thread-1" prio=6 tid=0x00000000065bb800 nid=0xaa4 in Object.wait() [0x0000000006f4e000]
   java.lang.Thread.State: RUNNABLE
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at java.lang.Class.newInstance0(Class.java:357)
	at java.lang.Class.newInstance(Class.java:310)
	at sun.misc.Service$LazyIterator.next(Service.java:282)
	at java.sql.DriverService.run(DriverManager.java:664)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:506)
	at java.sql.DriverManager.initialize(DriverManager.java:612)
	at java.sql.DriverManager.registerDriver(DriverManager.java:281)
	- locked <0x000000077cf5cc38> (a java.lang.Class for java.sql.DriverManager)
	at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:188)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:249)
	at com.fable.hamal.node.core.classthreads.InnerOracleThread.run(InnerOracleThread.java:15)

   Locked ownable synchronizers:
	- None

"Thread-0" prio=6 tid=0x00000000065ba800 nid=0x11c4 waiting for monitor entry [0x0000000006e4e000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.sql.DriverManager.registerDriver(DriverManager.java:280)
	- waiting to lock <0x000000077cf5cc38> (a java.lang.Class for java.sql.DriverManager)
	at com.mysql.jdbc.Driver.<clinit>(Driver.java:65)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:249)
	at com.fable.hamal.node.core.classthreads.InnerMysqlThread.run(InnerMysqlThread.java:15)

   Locked ownable synchronizers:
	- None


 

问题分析到线程:[Thread-0]被阻塞在lock <0x000000077cf5cc38>,而[Thread-1]持有lock <0x000000077cf5cc38>,但是却一直处在运行sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)方法中不结束,由于水平有限,不知道如何处理了。

 

RednaxelaFX 2013-12-27
我大概知道问题在哪里,不过为了确认,请楼主试试在死锁的时候用 jstack -m <pid> 来查一下线程栈的状况好吗?

另外拜托楼主先发一下使用的JDK版本和操作系统是什么(如果是Windows并且在用JDK6的话请升级到JDK7再试我前面说的命令)。
red_xie 2013-12-27
恩。操作系统是Windows7Sp1,JDK是1.6.0_45,正在按你说的测试。JDK1.7.0_45也不继续执行但是没有被blocked掉,等下测试完把结果贴出来。
red_xie 2013-12-27

1.6.0_45,jstack -m 出错和这个信息一样:http://hllvm.group.iteye.com/group/topic/39208#256533

red_xie 2013-12-27

JDK1.7.0_45:
线程dump:

 

"Thread-1" prio=6 tid=0x000000000c2a1800 nid=0xfdc in Object.wait() [0x000000000c9dd000]
   java.lang.Thread.State: RUNNABLE
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
	at java.lang.Class.newInstance(Class.java:374)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:373)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:445)
	at java.sql.DriverManager$2.run(DriverManager.java:510)
	at java.sql.DriverManager$2.run(DriverManager.java:490)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:490)
	at java.sql.DriverManager.<clinit>(DriverManager.java:100)
	at oracle.jdbc.driver.OracleDriver.<clinit>(OracleDriver.java:188)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at com.fable.hamal.node.core.classthreads.InnerOracleThread.run(InnerOracleThread.java:15)

   Locked ownable synchronizers:
	- None

"Thread-0" prio=6 tid=0x000000000c2a0800 nid=0xc0 in Object.wait() [0x000000000c80e000]
   java.lang.Thread.State: RUNNABLE
	at com.mysql.jdbc.Driver.<clinit>(Driver.java:65)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at com.fable.hamal.node.core.classthreads.InnerMysqlThread.run(InnerMysqlThread.java:15)

   Locked ownable synchronizers:
	- None

 

red_xie 2013-12-27

JDK1.7.0_45,  jstack -m信息:

 

 

Attaching to process ID 5952, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.45-b08
Deadlock Detection:

No deadlocks found.

----------------- 0 -----------------
0x00000000774f135a      ntdll!NtWaitForSingleObject + 0xa
0xec8b485741564155              ????????
sun.jvm.hotspot.debugger.DebuggerException: Windbg Error: ReadVirtual failed!
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readBytesFromProc
ess0(Native Method)
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readBytesFromProc
ess(WindbgDebuggerLocal.java:485)
        at sun.jvm.hotspot.debugger.DebuggerBase$Fetcher.fetchPage(DebuggerBase.
java:76)
        at sun.jvm.hotspot.debugger.PageCache.getPage(PageCache.java:178)
        at sun.jvm.hotspot.debugger.PageCache.getLong(PageCache.java:100)
        at sun.jvm.hotspot.debugger.DebuggerBase.readCInteger(DebuggerBase.java:
356)
        at sun.jvm.hotspot.debugger.DebuggerBase.readAddressValue(DebuggerBase.j
ava:454)
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readAddress(Windb
gDebuggerLocal.java:316)
        at sun.jvm.hotspot.debugger.windbg.WindbgAddress.getAddressAt(WindbgAddr
ess.java:72)
        at sun.jvm.hotspot.debugger.cdbg.basic.amd64.AMD64CFrame.sender(AMD64CFr
ame.java:55)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:161)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:53)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:48)
        at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
        at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.tools.jstack.JStack.runJStackTool(JStack.java:136)
        at sun.tools.jstack.JStack.main(JStack.java:102)
----------------- 1 -----------------
----------------- 2 -----------------
----------------- 3 -----------------
----------------- 4 -----------------
0x00000000774f135a      ntdll!NtWaitForSingleObject + 0xa
----------------- 5 -----------------
0x00000000774f135a      ntdll!NtWaitForSingleObject + 0xa
sun.jvm.hotspot.debugger.UnalignedAddressException: b79f0e9
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal$1.checkAlignment(
WindbgDebuggerLocal.java:104)
        at sun.jvm.hotspot.debugger.DebuggerBase.readCInteger(DebuggerBase.java:
349)
        at sun.jvm.hotspot.debugger.DebuggerBase.readAddressValue(DebuggerBase.j
ava:454)
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readAddress(Windb
gDebuggerLocal.java:316)
        at sun.jvm.hotspot.debugger.windbg.WindbgAddress.getAddressAt(WindbgAddr
ess.java:72)
        at sun.jvm.hotspot.debugger.cdbg.basic.amd64.AMD64CFrame.sender(AMD64CFr
ame.java:55)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:161)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:53)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:48)
        at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
        at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.tools.jstack.JStack.runJStackTool(JStack.java:136)
        at sun.tools.jstack.JStack.main(JStack.java:102)
----------------- 6 -----------------
0x00000000774f135a      ntdll!NtWaitForSingleObject + 0xa
sun.jvm.hotspot.debugger.UnalignedAddressException: b8df409
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal$1.checkAlignment(
WindbgDebuggerLocal.java:104)
        at sun.jvm.hotspot.debugger.DebuggerBase.readCInteger(DebuggerBase.java:
349)
        at sun.jvm.hotspot.debugger.DebuggerBase.readAddressValue(DebuggerBase.j
ava:454)
        at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readAddress(Windb
gDebuggerLocal.java:316)
        at sun.jvm.hotspot.debugger.windbg.WindbgAddress.getAddressAt(WindbgAddr
ess.java:72)
        at sun.jvm.hotspot.debugger.cdbg.basic.amd64.AMD64CFrame.sender(AMD64CFr
ame.java:55)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:161)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:53)
        at sun.jvm.hotspot.tools.PStack.run(PStack.java:48)
        at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
        at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
        at sun.jvm.hotspot.tools.JStack.main(JStack.java:86)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at sun.tools.jstack.JStack.runJStackTool(JStack.java:136)
        at sun.tools.jstack.JStack.main(JStack.java:102)
----------------- 7 -----------------
0x00000000774f135a      ntdll!NtWaitForSingleObject + 0xa

 

RednaxelaFX 2013-12-27
red_xie 写道
1.6.0_45,jstack -m 出错和这个信息一样:[url]http://hllvm.group.iteye.com/group/topic/39208#post-256533[/url

这个正常。别在Windows/JDK6上用SA系的工具(jstack -m与-F都是SA系的)

red_xie 写道
JDK1.7.0_45:
线程dump:


"Thread-1" prio=6 tid=0x000000000c2a1800 nid=0xfdc in Object.wait() [0x000000000c9dd000]
   java.lang.Thread.State: RUNNABLE
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
	at java.lang.Class.newInstance(Class.java:374)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:373)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:445)
	at java.sql.DriverManager$2.run(DriverManager.java:510)
	at java.sql.DriverManager$2.run(DriverManager.java:490)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:490)
	at java.sql.DriverManager.(DriverManager.java:100)
	at oracle.jdbc.driver.OracleDriver.(OracleDriver.java:188)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at com.fable.hamal.node.core.classthreads.InnerOracleThread.run(InnerOracleThread.java:15)

   Locked ownable synchronizers:
	- None

"Thread-0" prio=6 tid=0x000000000c2a0800 nid=0xc0 in Object.wait() [0x000000000c80e000]
   java.lang.Thread.State: RUNNABLE
	at com.mysql.jdbc.Driver.(Driver.java:65)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:270)
	at com.fable.hamal.node.core.classthreads.InnerMysqlThread.run(InnerMysqlThread.java:15)

   Locked ownable synchronizers:
	- None



不-m也没啥用…

red_xie 写道
JDK1.7.0_45, jstack -m信息

呃全是SA自己的错误。我以为这个bug早就修好了。明明修了嘛怎么还这样… https://bugs.openjdk.java.net/browse/JDK-6313816

至于死锁的问题回头分析。先吃晚饭去…
red_xie 2013-12-27
引用
至于死锁的问题回头分析。先吃晚饭去…


这是什么节奏,在美国么?
nijiaben 2014-07-08
red_xie 写道

问题描述:

两个线程,一个线程加载加载Mysql驱动,一个加载Oracle驱动,然后被阻塞在Class.forName()

最近正好也碰到此问题,我这记录了下,可以看看《JDK的sql设计不合理导致的驱动类初始化死锁问题》

 

http://lovestblog.cn/blog/2014/07/08/jdk-sql-deadlock/

 

ZHH2009 2014-07-09
这应该不是JDBC设计的问题,多半是并发类加载的问题,
我在jdk 1.6.0_29/1.7.0_10上都能重现deadlock,

但是在jdk 1.8.0-b132上面就没法重现了,
可以对比一下1.8和1.7的相关代码看看修改了哪些地方,
或看看1.8的代码提交记录是否有fix过什么特别的bug。
Global site tag (gtag.js) - Google Analytics