从另一个线程访问 servlet 作用域 bean [英] Accessing servlet scoped beans from another thread

查看:37
本文介绍了从另一个线程访问 servlet 作用域 bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用来自访问线程内的作用域代理bean"的答案.但是,我看到了涉及 RequestAttributes 对象的罕见死锁.死锁的主要原因是对象中的 synchronized (this.sessionAttributesToUpdate) 语句与 servlet 会话哈希映射之间.通常为每个请求创建对象的实例,因此它们不会发生冲突,但是如果我将对象传递给另一个线程以使用会话 bean,则会使用相同的对象,有时会导致死锁.

I am using approach from the "Accessing scoped proxy beans within Threads of" answer. However I am seeing rare deadlocks involving RequestAttributes object. The main reason of the deadlock is between the synchronized (this.sessionAttributesToUpdate) statement in the object and servlet session hash-map. Normally the instances of the object are created for each request, so they don't clash, but if I pass the object to another thread to use the session beans, the same object is used and it causes deadlock sometimes.

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

The deadlock happens if current http request is not completed while the another thread starts using a session bean passed with RequestContextHolder.setRequestAttributes.

我认为这个人提到了同样的问题,但他的问题没有得到解答:会话作用域 bean 遇到死锁.

I think this guy mentions the same problem, but his question is unanswered: Session scoped bean encountering deadlock.

那么,有什么办法可以避免僵局吗?

So, any ideas how to avoid the deadlock?

推荐答案

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

Here's an answer that provides alternative solution considering the objective is to calculate something in background while user is navigating pages.

可能性 1:使用@Async (http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html) 返回 Future 对象中的计算结果.将 Future 对象存储在会话中.如果任务完成,则通过 Future 对象访问后续请求中的结果.如果在任务完成前要销毁会话,则通过 Future.cancel 取消任务.

Possibility 1: Create a service bean with processing method that is annotated with @Async (http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html) that returns a result of computation in a Future object. Store the Future object in the session. Access the result in subsequent requests through Future object if task is completed. Cancel the the task via Future.cancel if session is to be destroyed before task is completed.

可能性 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

Possibility 2: Take a look if new features of Spring 3.2 and Servlet 3.0 async processing can help you: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/mvc.html#mvc-ann-async

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

Possibility 3: Emulate a task queue. Create a singleton service that can put objects to structure like ConcurrentMap where key would be some job id (you can than store key into session) and value the result of background processing. Background thread would then store objects there (this is perhaps not much better than accessing session directly, but you can make sure it's thread safe).

这篇关于从另一个线程访问 servlet 作用域 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆