2 u012151754 u012151754 于 2016.02.29 11:50 提问

单线程循环假死,纠结了一星期了,求指导

现在我正在维护一个派单系统,派单的业务逻辑是新起了一个线程,这个派单线程并没有
用到线程池之类的技术,就是一个很简单的new Thread().start(),然后有一个监听线程观察
该线程是否存活,如果不存活就重新再创建一个派单线程,但是现在有一个奇怪的问题,就是
运行大概一天左右,派单线程就会出现假死状态,但是通过ThreadDump发现该线程的状态
是Running,而每次派单线程都卡在一个Hibernate的get查询上,并且ThreadDump发现在该
线程上有获取数据库(mysql)collection的lock,求各位大神指导一下。
线程卡在这一条语句上:newMetaData=HibernateTemplateEx.getInstance().get(OdMetaData.class, busDate);
ThreadDump信息是:
"AutoAssignerThread_50" - Thread t@84
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:114)
at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:161)
at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:189)
- locked (a com.mysql.jdbc.util.ReadAheadInputStream)
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:3163)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3620)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3609)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4160)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2828)
- locked (a com.mysql.jdbc.JDBC4Connection)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2777)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1651)
- locked (a com.mysql.jdbc.JDBC4Connection)
at org.apache.commons.dbcp.DelegatingStatement.executeQuery(DelegatingStatement.java:208)
at org.apache.commons.dbcp.PoolableConnectionFactory.validateConnection(PoolableConnectionFactory.java:658)
at org.apache.commons.dbcp.PoolableConnectionFactory.validateObject(PoolableConnectionFactory.java:635)
at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:991)
at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:79)
at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:106)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java:81)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167)
at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:161)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1700)
at org.hibernate.loader.Loader.doQuery(Loader.java:801)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2037)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:86)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:76)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3294)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:496)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:477)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:227)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1090)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:1005)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:998)
at org.springframework.orm.hibernate3.HibernateTemplate$1.doInHibernate(HibernateTemplate.java:519)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:512)
at org.springframework.orm.hibernate3.HibernateTemplate.get(HibernateTemplate.java:506)
at net.xiaofei.workflow.assignment.autodecider.OdParameterCacheHelper.checkOdStatus(OdParameterCacheHelper.java:307)
at net.xiaofei.workflow.assignment.autodecider.WorkFlowCaseDistributeThread.run(WorkFlowCaseDistributeThread.java:63)

Locked ownable synchronizers:
- None

2个回答

ellisg
ellisg   2016.02.29 11:57

那问题就是产生在线程内的业务逻辑中了。对于数据库的操作中进行lock后,该lock由于某些操作繁忙,或其他逻辑异常导致没有解锁,是很正常的事情。还是建议好好理顺一下线程内的业务逻辑处理。或者调整下业务处理的逻辑,避免在get数据的时候使用lock,毕竟查询的时间要更多。

u012151754
u012151754 但是OdMetaData这张表在整个业务逻辑中很少被修改,大部分都是被查询的,并且出问题后,看了下数据库,并没有发现死锁
接近 2 年之前 回复
u012151754
u012151754   2016.02.29 12:05

但是OdMetaData这张表在整个业务逻辑中很少被修改,大部分都是被查询的,并且出问题后,看了下数据库,并没有发现死锁

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!