java - 同步方法与mysql连接池创建死锁

标签 java synchronization deadlock

我读了很多帖子

5 things you don't know about synchronization
Avoid synchronized this
Synchronized method access in java

我对可能发生死锁的可能情况有点熟悉,但我很惊讶地在下面的代码中看到死锁,到底是什么导致了它,???对我来说是一个大问号???

我的代码:

public class MySqlDB 
{
    private Connection connection = null;
    //private Statement statement = null;
    private DataSource datasource = null;
    private Object lockOnTransactionSql = new Object();

    public MySqlDB(String username, String password) 
    {           
        PoolProperties p = new PoolProperties();            
        p.setUrl("jdbc:mysql://localhost:3306/test?autoReconnect=true");
        p.setUsername(username);
        p.setPassword(password);
        p.setDriverClassName("org.mariadb.jdbc.Driver");            
        datasource = new DataSource();
        datasource.setPoolProperties(p);
    }

    private synchronized Statement getStatement() throws SQLException //THIS FUNCTION SOME TIME GOES IN LOCK MODE AND WAITING FOR HOURS BUT IT NEVER RETRUNS
    {       
        if(connection==null || connection.isClosed())
        {
            if(connection != null)
                connection.close();
            connection = datasource.getConnection();
        }
        return connection.createStatement();        
    }

    public void ProcessTransactionSql(ArrayList<String> queries) throws Exception
    {
        synchronized (lockOnTransactionSql) 
        {
            Statement statement = null;
            Connection connection = null;
            try
            {
                connection = datasource.getConnection();                
                connection.setAutoCommit(false);
                statement = connection.createStatement();
                for (String query : queries) 
                    statement.execute(query);
                connection.commit();
            }
            catch (Exception e)
            {
                connection.rollback();
                throw e;
            }
            finally
            {
                connection.setAutoCommit(true);         
                statement.close();              
                connection.close();
            }
        }
    }

    public ResultSet ProcessSelectSql(String sql) throws Exception 
    {   
        return  getStatement().executeQuery(sql);
    }

    public boolean ProcessUpdateSql(String sql) throws Exception
    {
        Statement st = null;
        Connection connection = null;
        try
        {           
            connection = datasource.getConnection();
            st = connection.createStatement();
            return st.execute(sql);
        }
        finally
        {       
            st.close();
            connection.close();
        }
    }
}

在上面的代码中,ProcessSelectSqlProcessTransactionSqlProcessUpdateSql 是从多个函数并行调用的函数,但在 Linux 计算机上运行几个小时或几天后,就会发生死锁。
观察到 getStatement 是从不返回语句的函数。

我的问题是可能发生死锁的原因是什么

需要强调的要点:

  • 我有两个可运行的 jar 在 Linux 机器上运行,它们使用 相同的数据库 test 和相同的类 MySqlDB 执行各种操作 对数据库的操作。
  • 这两个 jar 确实可以相互通信。

编辑我能够重新创建死锁并使用命令java -3 pid_of_java_jar来获取堆栈跟踪,它是

"RMI TCP Connection(597)-127.0.0.1" #160957 daemon prio=5 os_prio=0 tid=0x00007f5c6400e800 nid=0x9405 waiting for monitor entry [0x00007f5cd6a98000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(590)-127.0.0.1" #160952 daemon prio=5 os_prio=0 tid=0x00007f5c64005000 nid=0xb9dd waiting for monitor entry [0x00007f5cd7ffc000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(589)-127.0.0.1" #160951 daemon prio=5 os_prio=0 tid=0x00007f5c64001000 nid=0xa172 waiting for monitor entry [0x00007f5cdc434000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(588)-127.0.0.1" #160950 daemon prio=5 os_prio=0 tid=0x00007f5c6400c000 nid=0x6809 waiting for monitor entry [0x00007f5cd6c9a000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(534)-127.0.0.1" #160897 daemon prio=5 os_prio=0 tid=0x00007f5c64008800 nid=0xecc6 waiting for monitor entry [0x00007f5cd6997000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(435)-127.0.0.1" #160801 daemon prio=5 os_prio=0 tid=0x00007f5c64002800 nid=0x94c1 waiting for monitor entry [0x00007f5cd6b99000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFileDetails(SourceFile:3324)
    at com.mytest.service.RMIHandler.GetFileDetails(SourceFile:726)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Connection(431)-127.0.0.1" #160793 daemon prio=5 os_prio=0 tid=0x00007f5c64007800 nid=0xfc2e waiting for monitor entry [0x00007f5cd7efb000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.DeviceDB.GetDeviceId(SourceFile:565)
    at com.mytest.service.RMIHandler.ProcessSyncCycle(SourceFile:698)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$65(TCPTransport.java:683)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/1295046191.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"Thread-34026" #102332 daemon prio=5 os_prio=0 tid=0x00007f5c28006000 nid=0x7817 waiting for monitor entry [0x00007f5cd6d9d000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.AreaDB.GetDeviceArea(SourceFile:236)
    at com.mytest.service.ListMgr.SubmitJob(SourceFile:187)
    at com.mytest.service.ListMgr$2.run(SourceFile:137)
    at java.lang.Thread.run(Thread.java:745)

"Java2D Disposer" #37059 daemon prio=10 os_prio=0 tid=0x00007f5c2401a000 nid=0x4bbf in Object.wait() [0x00007f5cdccac000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x00000006cc9ffd18> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at sun.java2d.Disposer.run(Disposer.java:148)
    at java.lang.Thread.run(Thread.java:745)

"Thread-49" #146 daemon prio=5 os_prio=0 tid=0x00007f5c6c05e800 nid=0xd30c waiting for monitor entry [0x00007f5cdc8a9000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.UserDB.GetUsers(SourceFile:718)
    at com.mytest.service.CService.ProcessJob(SourceFile:553)
    at com.mytest.service.CService.ProcessJob(SourceFile:648)
    at com.mytest.service.ListMgr.run(SourceFile:98)
    at java.lang.Thread.run(Thread.java:745)

"Thread-48" #145 daemon prio=5 os_prio=0 tid=0x00007f5c6c03b800 nid=0xd30b waiting for monitor entry [0x00007f5cddaba000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
    - waiting to lock <0x00000006d5c4d808> (a java.io.BufferedInputStream)
    at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:82)
    at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:92)
    at org.mariadb.jdbc.internal.common.packet.RawPacket.nextPacket(RawPacket.java:82)
    at org.mariadb.jdbc.internal.common.packet.SyncPacketFetcher.getRawPacket(SyncPacketFetcher.java:67)
    at org.mariadb.jdbc.internal.common.queryresults.StreamingSelectResult.next(StreamingSelectResult.java:85)
    at org.mariadb.jdbc.internal.common.queryresults.CachedSelectResult.createCachedSelectResult(CachedSelectResult.java:77)
    at org.mariadb.jdbc.internal.mysql.MySQLProtocol.createQueryResult(MySQLProtocol.java:815)
    at org.mariadb.jdbc.internal.mysql.MySQLProtocol.getResult(MySQLProtocol.java:951)
    at org.mariadb.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:982)
    at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:280)
    - locked <0x00000006d5c4d0b8> (a org.mariadb.jdbc.internal.mysql.MySQLProtocol)
    at org.mariadb.jdbc.MySQLStatement.executeQuery(MySQLStatement.java:301)
    at org.mariadb.jdbc.MySQLStatement.executeQuery(MySQLStatement.java:360)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFilesToProcess(SourceFile:1880)
    at com.mytest.service.CService.SubmitJob(SourceFile:1093)
    at com.mytest.service.ListMgr$2.run(SourceFile:137)
    at java.lang.Thread.run(Thread.java:745)

"Thread-15" #46 prio=5 os_prio=0 tid=0x00007f5c30001000 nid=0xac80 waiting on condition [0x00007f5cdcbab000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000006d5c4daa0> (a java.util.concurrent.locks.ReentrantReadWriteLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
    at java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock(ReentrantReadWriteLock.java:943)
    at org.apache.tomcat.jdbc.pool.PooledConnection.lock(PooledConnection.java:609)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.returnConnection(ConnectionPool.java:893)
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:100)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:61)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
    at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:153)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
    at org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:41)
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109)
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80)
    at com.sun.proxy.$Proxy0.close(Unknown Source)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:37)
    - locked <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.UserDB.GetUsers(SourceFile:718)
    at com.mytest.service.TService.a(SourceFile:38)
    at com.mytest.service.TService$2.run(SourceFile:301)
    at java.lang.Thread.run(Thread.java:745)

"Thread-14" #45 daemon prio=5 os_prio=0 tid=0x00007f5c5000d800 nid=0xa363 waiting for monitor entry [0x00007f5cdd5b5000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.DeviceDB.GetDeviceId(SourceFile:565)
    at com.mytest.service.MDeviceMap.a(SourceFile:41)
    at com.mytest.service.MDeviceMap$1.run(SourceFile:113)
    at java.lang.Thread.run(Thread.java:745)

"Thread-11" #37 prio=5 os_prio=0 tid=0x00007f5c6c03e000 nid=0x1dd4 waiting for monitor entry [0x00007f5cdcdad000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.FileDB.GetFilePath(SourceFile:3928)
    at com.mytest.service.SService.d(SourceFile:712)
    at com.mytest.service.SService.a(SourceFile:129)
    at com.mytest.service.SService.a(SourceFile:38)
    at com.mytest.service.SService$1.run(SourceFile:102)
    at java.lang.Thread.run(Thread.java:745)

"Thread-10" #36 prio=5 os_prio=0 tid=0x00007f5c6c03f000 nid=0x1dca waiting for monitor entry [0x00007f5cdceae000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.mytest.dbhelper.MySqlDB.getStatement(SourceFile:32)
    - waiting to lock <0x00000006c5e79580> (a java.lang.Object)
    at com.mytest.dbhelper.MySqlDB.ProcessSelectSql(SourceFile:466)
    at com.mytest.filemanager.DeviceDB.GetDevices(SourceFile:1674)
    at com.mytest.service.TService.ThService(SourceFile:171)
    at com.mytest.service.TService$1.run(SourceFile:135)
    at java.lang.Thread.run(Thread.java:745)

"PoolCleaner[1550089733:1450166181974]" #12 daemon prio=5 os_prio=0 tid=0x00007f5cfc625800 nid=0x1d94 runnable [0x00007f5cde9c1000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:170)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
    - locked <0x00000006d5c4d808> (a java.io.BufferedInputStream)
    at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:82)
    at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:92)
    at org.mariadb.jdbc.internal.common.packet.RawPacket.nextPacket(RawPacket.java:82)
    at org.mariadb.jdbc.internal.common.packet.SyncPacketFetcher.getRawPacket(SyncPacketFetcher.java:67)
    at org.mariadb.jdbc.internal.mysql.packet.MySQLRowPacket.getRow(MySQLRowPacket.java:86)
    at org.mariadb.jdbc.internal.common.queryresults.StreamingSelectResult.next(StreamingSelectResult.java:107)
    at org.mariadb.jdbc.internal.common.queryresults.StreamingSelectResult.close(StreamingSelectResult.java:123)
    at org.mariadb.jdbc.internal.mysql.MySQLProtocol.skip(MySQLProtocol.java:728)
    at org.mariadb.jdbc.internal.mysql.MySQLProtocol.close(MySQLProtocol.java:779)
    at org.mariadb.jdbc.MySQLConnection.close(MySQLConnection.java:249)
    at org.apache.tomcat.jdbc.pool.PooledConnection.disconnect(PooledConnection.java:331)
    at org.apache.tomcat.jdbc.pool.PooledConnection.release(PooledConnection.java:490)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.release(ConnectionPool.java:581)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.abandon(ConnectionPool.java:540)
    at org.apache.tomcat.jdbc.pool.ConnectionPool.checkAbandoned(ConnectionPool.java:958)
    at org.apache.tomcat.jdbc.pool.ConnectionPool$PoolCleaner.run(ConnectionPool.java:1347)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

"VM Periodic Task Thread" os_prio=0 tid=0x00007f5cfc22a800 nid=0x1d92 waiting on condition 

JNI global references: 478

Heap
 PSYoungGen      total 181760K, used 117101K [0x000000076c980000, 0x000000077e500000, 0x00000007c0000000)
  eden space 180736K, 64% used [0x000000076c980000,0x0000000773bdb500,0x0000000777a00000)
  from space 1024K, 0% used [0x0000000777a00000,0x0000000777a00000,0x0000000777b00000)
  to   space 54784K, 0% used [0x000000077af80000,0x000000077af80000,0x000000077e500000)
 ParOldGen       total 443392K, used 274009K [0x00000006c5c00000, 0x00000006e0d00000, 0x000000076c980000)
  object space 443392K, 61% used [0x00000006c5c00000,0x00000006d6796760,0x00000006e0d00000)
 Metaspace       used 24224K, capacity 24486K, committed 24832K, reserved 1071104K
  class space    used 2128K, capacity 2213K, committed 2304K, reserved 1048576K

最佳答案

驻留在两个不同 jar 中的两个不同应用程序正在访问 getStatement() 方法,该方法又创建一个作为 MySqlDB 实例字段创建的 Connection 对象。一般来说,我们应该避免共享连接,并为每个请求从池中获取连接,并在工作完成后关闭连接。您还可以尝试使用新的锁 API 并利用锁公平性和超时来避免死锁。是的,需要处理锁超时异常。

关于java - 同步方法与mysql连接池创建死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34058943/

相关文章:

mysql - 自己做MySQL行复制的问题

c++ - 如何实现动态线程Boost::Barrier?

java - 使用 3 个 PetersonLock 的数组来同步 4 个进程

c# - Protobuf.net 异常 - 检查元数据时超时

java - 从另一个 Controller 返回 PrimaryStage

java - OpenAM 12 的本地 Maven 依赖项

java - 下载JDK版本

c# - 造成僵局

java - Java 并发的困难时期

Java变量引用