死锁 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector

Posted julygift

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死锁 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector相关的知识,希望对你有一定的参考价值。

最近在IDEA中启动Tomcat经常会碰到这个错误,起初、一直没在意,现在碰到的次数多了,就去查看下这个问题,现描述如下:

=2018-01-08 14:27:30,216 WARN  [com.mchange.v2.async.ThreadPoolAsynchronousRunner] - com[email protected]29165a67 -- APPARENT DEADLOCK!!! Complete Status: 
    Managed Threads: 3
    Active Threads: 3
    Active Tasks: 
        [email protected]96 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
        [email protected]d5 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
        [email protected]63 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
    Pending Tasks: 
        [email protected]32
        [email protected]14
        [email protected]6e
        [email protected]20
        [email protected]bb
        [email protected]dd
        [email protected]c8
Pool thread stack traces:
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,RMI Runtime]
        java.net.PlainSocketImpl.socketConnect(Native Method)
        java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        java.net.Socket.connect(Socket.java:529)
        java.net.Socket.connect(Socket.java:478)
        java.net.Socket.<init>(Socket.java:375)
        java.net.Socket.<init>(Socket.java:189)
        oracle.net.nt.TcpNTAdapter.connect(Unknown Source)
        oracle.net.nt.ConnOption.connect(Unknown Source)
        oracle.net.nt.ConnStrategy.execute(Unknown Source)
        oracle.net.resolver.AddrResolution.resolveAndExecute(Unknown Source)
        oracle.net.ns.NSProtocol.establishConnection(Unknown Source)
        oracle.net.ns.NSProtocol.connect(Unknown Source)
        oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:844)
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:268)
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,RMI Runtime]
        java.net.PlainSocketImpl.socketConnect(Native Method)
        java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        java.net.Socket.connect(Socket.java:529)
        java.net.Socket.connect(Socket.java:478)
        java.net.Socket.<init>(Socket.java:375)
        java.net.Socket.<init>(Socket.java:189)
        oracle.net.nt.TcpNTAdapter.connect(Unknown Source)
        oracle.net.nt.ConnOption.connect(Unknown Source)
        oracle.net.nt.ConnStrategy.execute(Unknown Source)
        oracle.net.resolver.AddrResolution.resolveAndExecute(Unknown Source)
        oracle.net.ns.NSProtocol.establishConnection(Unknown Source)
        oracle.net.ns.NSProtocol.connect(Unknown Source)
        oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:844)
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:268)
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
    Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,RMI Runtime]
        java.net.PlainSocketImpl.socketConnect(Native Method)
        java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
        java.net.Socket.connect(Socket.java:529)
        java.net.Socket.connect(Socket.java:478)
        java.net.Socket.<init>(Socket.java:375)
        java.net.Socket.<init>(Socket.java:189)
        oracle.net.nt.TcpNTAdapter.connect(Unknown Source)
        oracle.net.nt.ConnOption.connect(Unknown Source)
        oracle.net.nt.ConnStrategy.execute(Unknown Source)
        oracle.net.resolver.AddrResolution.resolveAndExecute(Unknown Source)
        oracle.net.ns.NSProtocol.establishConnection(Unknown Source)
        oracle.net.ns.NSProtocol.connect(Unknown Source)
        oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:844)
        oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:268)
        oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)
        oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
        oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
        oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
        com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182)
        com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171)
        com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
        com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
        com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32)
        com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
        com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

在一番求知的过程中,大概了解到这个问题出现的几种可能情况,随记录下来,以供后人鉴赏:

1.数据库服务没有启动

大千世界无奇不有,这种错也有人遇到的话,真不想说什么了;如果是故意测试的话呢,个人感觉还是没有必要的,毕竟不开启数据库服务就去连接数据库,你让人作何感想啊。

2.没有创建对应数据库

这个问题同上,访问不到数据库,都不是技术性的问题,在此、不多啰嗦。

3.就涉及到c3p0连接池的配置文件了

这个问题就比较偏重于技术层面了,相关解决方案介绍如下:

①maxStatements 和checkoutTimeout

JDBC的标准参数,用以控制数据源内加载的PreparedStatements数量。但由于预缓存的statements属于单个connection而不是整个连接池。所以设置这个参数需要考虑到多方面的因素。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0。

通过上面的描述,解决方案:

<property name="maxStatements" value="0"/> 

<property name="checkoutTimeout" value="100"/> 

 ②maxPoolSize和initialPoolSize

关于这方面,我大概能够了解到我个人的问题是由于这个原因导致的。由于数据库的连接数是有限的,每有应用启动C3p0都会占用数据库的连接来填充C3p0的连接池,而当数据库的资源被占光时就会因为无法获得共享资源而报死锁。

③更新c3p0的包

至于c3p0的包版本过旧造成的,这大概是历史遗留的问题。低版本c3p0包会导致获取连接的时间过长而在获取新的连接时造成死锁,具体请参考stackoverflow中别人提出的一个问题

The tasks that are dealocking are Connection acquisition tasks. That is, c3p0 is trying to acquire new Connections from your database, and those Connection acquisition attempts are taking a long time.

The first thing I would do is upgrade to 0.9.2.1, which has a much improved means of performing a round of Connection acquisitions in situations where acquisition attempts sometimes fail.

If that doesn‘t solve your problem, then you‘ll need to figure out why c3p0‘s attempts to acquire a Connection are hanging for long periods of time: neither succeeding nor failing with an Exception.

以上是关于死锁 com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector的主要内容,如果未能解决你的问题,请参考以下文章

计算机操作系统 死锁 -- 产生死锁的必要条件死锁的处理方法(鸵鸟策略死锁检测与死锁恢复死锁预防死锁避免)

计算机操作系统 死锁 -- 产生死锁的必要条件死锁的处理方法(鸵鸟策略死锁检测与死锁恢复死锁预防死锁避免)

计算机操作系统 死锁 -- 产生死锁的必要条件死锁的处理方法(鸵鸟策略死锁检测与死锁恢复死锁预防死锁避免)

「操作系统」深入理解死锁(什么是死锁?死锁形成条件?如何避免死锁?如何排查死锁?)

死锁处理策略和死锁预防

死锁:操作系统的死锁检测算法,死锁避免算法,死锁预防算法,死锁检测