Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

多个线程调用DruidDataSource.init(), 会出现‘死锁’情况 #2980

Closed
ykl0826 opened this issue Dec 19, 2018 · 3 comments
Closed
Labels
Milestone

Comments

@ykl0826
Copy link

ykl0826 commented Dec 19, 2018

项目正在启动中,尚未加载过DriverManager类, `此时,外部有一个定时任务的调度中心正在往此项目发布多个调度任务,Thread-1获取到init()方法中的可重入锁之后执行后续代码,运行到this.id = DruidDriver.createDataSourceId();时会加载DruidDriver类,运行static块中的registerDriver(Driver driver),进而执行代码段DriverManager.registerDriver(driver)。Thread-2也进入init()方法,此时,Thread-2若被interrupted,则会进入throw new SQLException("interrupt", e),而SQLException的构造方法中有
if (DriverManager.getLogWriter() != null),进而执行DriverManager中的static块,应该是static块中的loadInitialDrivers会用到DruidDriver,而加载DruidDriver的线程Thread-1会用到DriverManager,两个线程相互等待,最终会导致两个线程永远不会结束。实际上就是两个线程分别进入了两个类的static块中,而static块中的都需要对方的资源,最终程序会出现‘死锁’的状态,jvisualvm无法检测到这种死锁。本人目前是新手兼菜鸟,如有说的不对的地方,烦请大神指点指点,谢谢。

下面代码可以复现这个问题,可以使用打断点的方式,也可以多运行几次。
`public class DruidDataSourceTestForDeadLock {

private static DruidDataSource source = new DruidDataSource();
private static void init() {
    try {
        source.init();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    Thread t1 = new Thread(() -> init());
    Thread t2 = new Thread(() -> init());
    t1.start();
    t2.start();
    t2.interrupt();
}

}`

上述程序可能会出现两个结果:
1 两个线程卡住,程序无法自动结束
2 程序正常结束,会报错,因为没有设置如数据库url之类的,这是正常的

这是上面这个程序在结果1的情况下dump下来的线程栈:
`"Thread-2" #15 prio=5 os_prio=0 tid=0x000000001d046000 nid=0x5b944 in Object.wait() [0x000000001ed9d000]
java.lang.Thread.State: RUNNABLE
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at java.lang.Class.newInstance(Class.java:442)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at java.sql.DriverManager$2.run(DriverManager.java:603)
at java.sql.DriverManager$2.run(DriverManager.java:583)
at java.security.AccessController.doPrivileged(Native Method)
at java.sql.DriverManager.loadInitialDrivers(DriverManager.java:583)
at java.sql.DriverManager.(DriverManager.java:101)
at java.sql.SQLException.(SQLException.java:190)
at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:746)
at DruidDeadLock.init(DruidDeadLock.java:14)
at DruidDeadLock.lambda$1(DruidDeadLock.java:22)
at DruidDeadLock$$Lambda$2/191382150.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

Locked ownable synchronizers:
- None

"Thread-1" #14 prio=5 os_prio=0 tid=0x000000001d045800 nid=0xd2cc at breakpoint[0x000000001e09d000]
java.lang.Thread.State: RUNNABLE
at com.alibaba.druid.proxy.DruidDriver.registerDriver(DruidDriver.java:92)
at com.alibaba.druid.proxy.DruidDriver$1.run(DruidDriver.java:84)
at java.security.AccessController.doPrivileged(Native Method)
at com.alibaba.druid.proxy.DruidDriver.(DruidDriver.java:81)
at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:757)
at DruidDeadLock.init(DruidDeadLock.java:14)
at DruidDeadLock.lambda$0(DruidDeadLock.java:21)
at DruidDeadLock$$Lambda$1/997110508.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

Locked ownable synchronizers:
- <0x000000076b9d7ae0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)

`

@wenshao wenshao added the Bug label Dec 21, 2018
@wenshao wenshao added this to the 1.1.12 milestone Dec 21, 2018
@wenshao
Copy link
Member

wenshao commented Dec 21, 2018

请问是druid什么版本?

@ykl0826
Copy link
Author

ykl0826 commented Dec 21, 2018

请问是druid什么版本?

请问是druid什么版本?

大神你好,最初是在1.0.27版本上出现的问题,后来在1.1.12版本中也复现了这个问题

@wenshao
Copy link
Member

wenshao commented Jan 31, 2019

https://github.com/alibaba/druid/releases/tag/1.1.13 问题已修复,请用新版本

@wenshao wenshao closed this as completed Jan 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants