Java 当线程全部为空时,C3P0 明显死锁?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3730844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C3P0 apparent deadlock when the threads are all empty?
提问by Steven Schlansker
I'm using C3P0 as a connection pool in Tomcat, and I'm seeing very worrying errors:
我在 Tomcat 中使用 C3P0 作为连接池,我看到了非常令人担忧的错误:
2010-09-16 13:25:00,160 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2010-09-16 13:25:01,407 [Timer-0] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner - com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@43502400 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 10
Active Threads: 0
Active Tasks:
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePoolRefurbishCheckinResourceTask@6e4151a7
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#6,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#5,5,main]
java.lang.Object.wait(Native Method)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:534)
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#4,5,main]
java.lang.Object.wait(Native Method)
... many more, exact same stack trace
Line 534 is:
第 534 行是:
while (true) {
Runnable myTask;
synchronized ( ThreadPoolAsynchronousRunner.this ) {
while ( !should_stop && pendingTasks.size() == 0 )
ThreadPoolAsynchronousRunner.this.wait( POLL_FOR_STOP_INTERVAL ); // <- here
if (should_stop) ...
It looks very much like all the threads are idle. They're waiting for work. 0 active threads, and only 1 task to complete. Any clues on what's going wrong?
看起来很像所有线程都处于空闲状态。他们在等工作。0 个活动线程,只有 1 个任务需要完成。关于出了什么问题的任何线索?
Here's the configuration:
这是配置:
ds.setUser(userName);
ds.setPassword(password);
ds.setMaxPoolSize(16);
ds.setMaxConnectionAge(1800);
ds.setAcquireRetryAttempts(4);
ds.setMaxIdleTime(900);
ds.setNumHelperThreads(10);
ds.setCheckoutTimeout(1000);
回答by Thomas Weber
This sounds like you have already acquired a connection from the pool and do not return it in time.
这听起来像您已经从池中获取了一个连接并且没有及时返回它。
C3P0 determines "apparent deadlocks" when a connection is acquired but not returned to the pool within the deadlock detection timeout.
当获取连接但未在死锁检测超时内返回到池时,C3P0 确定“明显死锁”。
If you move the connection acquisition closer to the "action" and immediately return it to the pool after the database work is done, this message will disappear.
如果将连接获取移近“动作”并在数据库工作完成后立即将其返回到池中,则此消息将消失。
回答by ChristiaanP
This will sort out your problem
这将解决您的问题
ds.setMaxStatements(1000);
ds.setMaxStatementsPerConnection(100); (the maximum number of prepared statments your system can execute on a single connection)
check out : https://forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0
退房:https: //forum.hibernate.org/viewtopic.php?t=947246&highlight=apparent+deadlock+c3p0
Remember to close your statements after you are done with them !!
完成后记得关闭你的陈述!!
回答by Zon
I had the same (was unable to detect) problem solved by correctly closing Statement and Resultset instances (somehow left unclosed):
我通过正确关闭 Statement 和 Resultset 实例(不知何故未关闭)解决了相同的(无法检测到)问题:
String SQL = "SELECT 1";
try {
con = DriverManager.getConnection(host, userName, userPassword);
stmt = con.prepareStatement(SQL, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
try {
rs = stmt.executeQuery(SQL);
try {
rs.next();
// ...
} finally {
rs.close();
}
} finally {
stmt.close();
}
} catch (SQLException ex) {
Logger.getLogger(MyClass.class.getName()).log(Level.SEVERE, null, ex);
}
回答by eebbesen
I just experienced a similar issue against an Oracle database, but in my case Managed Thread
and Active Thread
counts were the same.
我刚刚遇到了针对 Oracle 数据库的类似问题,但在我的情况下Managed Thread
,Active Thread
计数是相同的。
Managed Threads: 3
Active Threads: 3
For me it was actually an authentication error but appeared as the APPARENT DEADLOCK
error because of the way I was doing login auditing.
对我来说,这实际上是一个身份验证错误,但APPARENT DEADLOCK
由于我进行登录审核的方式而显示为错误。
2013-08-12 11:29:04,910 [Timer-4] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@34996454 -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!
2013-08-12 11:29:04,914 [Timer-4] WARN com.mchange.v2.async.ThreadPoolAsynchronousRunner: com.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@34996454 -- APPARENT DEADLOCK!!! Complete Status:
Managed Threads: 3
Active Threads: 3
Active Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@6730b844 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2)
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@2f91ad49 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0)
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@507ac05 (com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#1)
Pending Tasks:
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@3aae7ed7
Pool thread stack traces:
Thread[com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#2,5,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:150)
java.net.SocketInputStream.read(SocketInputStream.java:121)
oracle.net.ns.Packet.receive(Packet.java:300)
oracle.net.ns.DataPacket.receive(DataPacket.java:106)
oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760)
oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
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.C3P0PooledConnectionPoolPooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
com.mchange.v2.resourcepool.BasicResourcePool.access0(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-#0,5,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:150)
java.net.SocketInputStream.read(SocketInputStream.java:121)
oracle.net.ns.Packet.receive(Packet.java:300)
oracle.net.ns.DataPacket.receive(DataPacket.java:106)
oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760)
oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
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.C3P0PooledConnectionPoolPooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
com.mchange.v2.resourcepool.BasicResourcePool.access0(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,main]
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:150)
java.net.SocketInputStream.read(SocketInputStream.java:121)
oracle.net.ns.Packet.receive(Packet.java:300)
oracle.net.ns.DataPacket.receive(DataPacket.java:106)
oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:380)
oracle.jdbc.driver.T4CTTIoauthenticate.doOAUTH(T4CTTIoauthenticate.java:760)
oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:401)
oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
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.C3P0PooledConnectionPoolPooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137)
com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014)
com.mchange.v2.resourcepool.BasicResourcePool.access0(BasicResourcePool.java:32)
com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810)
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
回答by atzu
I've had the same problem but the cause was a bit hard to spot as it was caused by some simultaneous resources trying to acquire a connection at the same time.
我遇到了同样的问题,但原因有点难以发现,因为它是由一些同时尝试同时获取连接的资源引起的。
As you can read if the pool had not been initialized the code provided to init it by calling a setup function.
如您所见,如果池尚未初始化,则提供了通过调用 setup 函数来初始化它的代码。
public Connection getConnection() throws SQLException {
if (mCPDS == null) {
setupPool();
}
return mCPDS.getConnection();
}
The problem was that many resources were trying to acquire the connection at the beginning of the program so more than one were instantiating the pool causing your problem after a while.
问题在于,许多资源在程序开始时试图获取连接,因此一段时间后,不止一个资源实例化导致您出现问题的池。
The solution was just to declare the method synchronized to keep out other resources while one has called the method and it's still inside instantiating the pool for instance.
解决方案只是声明方法同步以阻止其他资源,同时调用该方法并且它仍然在实例化池中。
public synchronized Connection getConnection() throws SQLException {
if (mCPDS == null) {
setupPool();
}
return mCPDS.getConnection();
}
This may be a design error for not using a singleton but fixes the problem lacking some performance.
这可能是不使用单例的设计错误,但修复了缺乏某些性能的问题。
回答by colin
We ran into this problem and solved it by adding this to the C3P0 config:
我们遇到了这个问题并通过将其添加到 C3P0 配置来解决它:
<property name="statementCacheNumDeferredCloseThreads" value="1"/>
as per: this from the C3P0 doc
根据:这来自 C3P0 文档
回答by packet
Similar problem was encountered on glassfish4 server while deploying the application. Turned out it was a database configuration issue. Just make sure your database connectivity configurations are proper, verify that the hostname provided in the configuration allows the connection to database. Try connecting to the database manually with the configured username and the hostname/domain. If required, allow the db user to connect from the required domain. Rebuild the application with correct db configurations and then deploy it.
部署应用程序时在 glassfish4 服务器上遇到了类似的问题。原来是数据库配置问题。只需确保您的数据库连接配置正确,验证配置中提供的主机名是否允许连接到数据库。尝试使用配置的用户名和主机名/域手动连接到数据库。如果需要,允许 db 用户从所需的域进行连接。使用正确的数据库配置重建应用程序,然后部署它。
回答by Alejandro Lopez Morales
Hi my friend just to comment, I had the same case. I just configured my spring-hibernate eclipse project and showed up the same exception, it should be noted that my project still does not have any query.
嗨,我的朋友只是发表评论,我有同样的情况。我刚刚配置了我的spring-hibernate eclipse项目并显示了相同的异常,需要注意的是我的项目仍然没有任何查询。
I resolved that issue with below steps:
我通过以下步骤解决了这个问题:
1) Clean project : Project--> Clean... 2) Build project : Project--> Build Project
1) 清理项目:项目--> 清理... 2) 构建项目:项目--> 构建项目
I hope it works for you.
我希望这个对你有用。
回答by HankCa
My comment on answer https://stackoverflow.com/a/18192588/1019307received enough up-votes to suggest it should be an answer.
我对答案https://stackoverflow.com/a/18192588/1019307 的评论收到了足够多的赞成票,表明它应该是一个答案。
I received this error because I couldn't get through the firewall to the database server.Check to see if that is your problem.
我收到此错误是因为我无法通过防火墙到达数据库服务器。检查是否是您的问题。
回答by Leviand
I've just had the same problem suddenly: after noticing that the deadlock was present only when launching my application in debug mode (I'm using IntelliJ) and it was fine when running with normal run, I started to dig it.
我突然遇到了同样的问题:在注意到仅在调试模式下启动我的应用程序时才存在死锁(我使用的是 IntelliJ)并且在正常运行时运行很好,我开始挖掘它。
I finally figured out that a breakpoint was blocking the connection: I don't know why Intellij didn't "listen" that the application was passing through that breakpoint, but was hanged somewhere cause of a breakpoint, and this was causing appartent deadlock
我终于发现断点正在阻塞连接:我不知道为什么 Intellij 没有“监听”应用程序正在通过该断点,而是由于断点而挂在某个地方,这导致了明显的死锁
After removing all breakpoints in my project, everything started smooth again.
删除我项目中的所有断点后,一切又开始顺利了。
Hope this helps someone
希望这有助于某人