【问题标题】:Spring Batch multithread throwing java.lang.Thread.StateSpring Batch 多线程抛出 java.lang.Thread.State
【发布时间】:2013-05-04 04:16:48
【问题描述】:

我有一个使用GrailsSpringJavaHibernate 开发的网络应用程序。

它包含一个使用Spring Batch 实现的批处理作业。当我在没有多线程的情况下运行作业时,它工作正常。一旦我在一些处理之后引入分区(并且每个分区都由不同的线程/多线程处理),一些线程就会陷入无限循环并且永远不会回来。

以下是线程卡住时的堆栈跟踪。

java.lang.Thread.State: RUNNABLE
at org.apache.commons.collections.map.AbstractHashedMap.getEntry(AbstractHashedMap.java:440)
at org.apache.commons.collections.map.AbstractReferenceMap.getEntry(AbstractReferenceMap.java:405)
at org.apache.commons.collections.map.AbstractReferenceMap.get(AbstractReferenceMap.java:230)
at org.grails.datastore.mapping.core.AbstractDatastore.getObjectErrors(AbstractDatastore.java:160)
at org.grails.datastore.mapping.core.Datastore$getObjectErrors.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.grails.datastore.mapping.core.Datastore$getObjectErrors.call(Unknown Source)
at org.grails.datastore.gorm.GormValidationApi.getErrors(GormValidationApi.groovy:137)
at sun.reflect.GeneratedMethodAccessor580.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1231)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1047)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1110)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:877)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:793)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:776)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:164)
at org.grails.datastore.gorm.InstanceMethodInvokingClosure.call(GormEnhancer.groovy:257)
at org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod.invoke(ClosureStaticMetaMethod.java:59)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1580)
at groovy.lang.ExpandoMetaClass.getProperty(ExpandoMetaClass.java:1140)
at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3308)
at groovy.lang.ExpandoMetaClass.getProperty(ExpandoMetaClass.java:1152)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractDynamicPersistentMethod.setupErrorsProperty(AbstractDynamicPersistentMethod.java:100)

这只是线程跟踪的一部分。

此跟踪仅告诉我线程卡住的方法。它没有告诉我任何细节,而且搜索问题的方法非常大。任何人都可以在这件事上帮助我告诉我:

1) 查看跟踪有什么问题?

2) 如何查看更详细的堆栈跟踪?

【问题讨论】:

  • 如果没有更多信息,很难说出确切的问题。根据导致问题的多线程行为,猜测是在数据库级别或代码内发生某种类型的争用。可能检查数据库是否存在争用。另一个想法是下载 apache commons 集合映射源代码并设置断点或尝试查看线程冻结时正在尝试的确切内容。

标签: multithreading spring hibernate grails grails-orm


【解决方案1】:

我也遇到过同样的问题。

我使用 grails 1.3.7,我的服务将完全陷入无限循环。

问题是 DomainClassGrailsPlugin 不是线程安全的

http://jira.grails.org/browse/GRAILS-7861

这是解决您问题的补丁

如果你的 grails 版本

修补此代码以替换 SoftThreadLocalMap.java 并重新安装 grails 应用程序

【讨论】:

  • 感谢您的回答。我正在使用 grails 2.0.3。看来这个问题已经在 2.0.3 中解决了。不知道为什么我的线程还在无限循环中。
  • 您的回答对发现问题很有帮助。谢谢
  • 我建议你用jconsole检查cpu是否总是等于100%(for one cpu core),看看是不是死循环问题。
  • 您的回答真的很有帮助,正如您在回答中提到的那样,问题出在 grails-datastore-core 文件中。 SoftThreadLocalMap.java 文件不是线程安全的。他们已经在 grails-datastore-core 版本 > 2 中解决了这个问题。感谢您的帮助。
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-13
  • 1970-01-01
  • 1970-01-01
  • 2019-07-14
  • 2018-08-17
相关资源
最近更新 更多