0

我正在使用“访问线程内的范围代理bean ”答案中的方法。但是我看到涉及RequestAttributes对象的罕见死锁。死锁的主要原因是synchronized (this.sessionAttributesToUpdate)对象中的语句和servlet session hash-map之间。通常为每个请求创建对象的实例,因此它们不会发生冲突,但是如果我将对象传递给另一个线程以使用会话 bean,则会使用相同的对象,并且有时会导致死锁。

如果当前的 http 请求没有完成,而另一个线程开始使用通过 传递的会话 bean,则会发生死锁RequestContextHolder.setRequestAttributes

我认为这个人提到了同样的问题,但他的问题没有得到解答:Session scoped bean遇到 deadlock

那么,任何想法如何避免僵局?

4

1 回答 1

0

考虑到目标是在用户浏览页面时在后台计算某些内容,这是一个提供替代解决方案的答案。

可能性1:创建一个带有@Async( http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html )注释的处理方法的服务bean,它返回一个Future中的计算结果目的。将 Future 对象存储在会话中。如果任务完成,则通过 Future 对象访问后续请求中的结果。如果要在任务完成之前销毁会话,请通过 Future.cancel 取消任务。

可能性 2:看看 Spring 3.2 和 Servlet 3.0 异步处理的新特性是否可以帮助您: http ://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html #mvc-ann-async

可能性 3:模拟一个任务队列。创建一个单例服务,可以将对象放入像 ConcurrentMap 这样的结构中,其中键是一些作业 ID(您可以将键存储到会话中)并评估后台处理的结果。然后后台线程将在那里存储对象(这可能并不比直接访问会话好多少,但您可以确保它是线程安全的)。

于 2013-04-02T18:00:20.040 回答