迭代Grails参数映射时出现间歇性ConcurrentModificationException
我偶尔会在grails应用程序的登录CI中看到下面的迭代Grails参数映射时出现间歇性ConcurrentModificationException,grails,concurrentmodification,Grails,Concurrentmodification,我偶尔会在grails应用程序的登录CI中看到下面的ConcurrentModificationException。我认为只有当应用程序负载很大时才会发生这种情况(我们在同一个tomcat实例上触发8个并发Geb测试碎片) getMostRecentPrefixedParams方法中的代码如下所示: private def getMostRecentPrefixedParams(params, session, prefix, sessionParamName) { synchroniz
ConcurrentModificationException
。我认为只有当应用程序负载很大时才会发生这种情况(我们在同一个tomcat实例上触发8个并发Geb测试碎片)
getMostRecentPrefixedParams
方法中的代码如下所示:
private def getMostRecentPrefixedParams(params, session, prefix, sessionParamName) {
synchronized (params) {
for (String key : params) { // line 83 - exception happens here
if (key.startsWith(prefix)) {
if (session != null) {
clearTags(params)
}
return params
}
}
}
if (session == null) {
return params
}
return session."${sessionParamName}" == null ? params : session."${sessionParamName}"
}
我添加了synchronized
块,试图阻止这种情况发生,但显然发生了其他事情
传递到getMostRecentPrefixedParams
方法的params
参数只是来自一个控制器(隐式params
controller属性)——据我所知,在整个请求/响应周期中,只有一个请求线程可以访问该映射,但即使情况并非如此,而且另一个线程以某种方式访问了该映射,我也会认为同步块会阻止ConcurrentModificationException
我们使用的是Grails 2.3.7。一个可能有用的技巧是在方法顶部打印stacktrace,这样您就可以看到另一个调用来自何处,例如
log.error'getMostRecentPrefixedParams',Grails.util.GrailsUtil.deepSanitize(新的异常('who reang?'))
谢谢Burt,我将给出一个trywhat is clearTags你能发布它的代码吗?问题可能是在这里,因为当你在地图上迭代时,你可能会从地图上删除一个项目?clearTags
只是将会话属性设置为null-谢谢你的建议。当然,在添加Burt建议的日志记录并运行构建十几次之后,我无法再重现错误。嗯……一个可能有用的技巧是在方法顶部打印一个stacktrace,这样您就可以看到另一个调用来自何处,例如log.error'getMostRecentPrefixedParams',grails.util.GrailsUtil.deepSanitize(新的异常('who-rang?'))
谢谢Burt,我给你一个trywhat是clearTags,你能发布它的代码吗,问题可能出在这里,因为您可能在对映射进行迭代时从映射中删除了一个项?clearTags
只是将会话属性设置为null——不过感谢您的建议。当然,在添加Burt建议的日志记录并运行构建十几次之后,我无法再重现错误。嗯……一个可能有用的技巧是在方法顶部打印一个stacktrace,这样您就可以看到另一个调用来自何处,例如log.error'getMostRecentPrefixedParams',grails.util.GrailsUtil.deepSanitize(新的异常('who-rang?'))
谢谢Burt,我给你一个trywhat是clearTags,你能发布它的代码吗,问题可能出在这里,因为您可能在对映射进行迭代时从映射中删除了一个项?clearTags
只是将会话属性设置为null——不过感谢您的建议。当然,在添加Burt建议的日志记录并运行构建十几次之后,我无法再重现错误。嗯。。。
private def getMostRecentPrefixedParams(params, session, prefix, sessionParamName) {
synchronized (params) {
for (String key : params) { // line 83 - exception happens here
if (key.startsWith(prefix)) {
if (session != null) {
clearTags(params)
}
return params
}
}
}
if (session == null) {
return params
}
return session."${sessionParamName}" == null ? params : session."${sessionParamName}"
}