r4j*_*j1v 8 java spring multithreading
场景:我们有一个在Websphere中运行的Spring托管Web应用程序.(Spring 3.0.x,WAS 7)webapp通过Spring WorkManagerTaskExecutor(配置线程池大小为10)利用Websphere的工作管理器来执行计算密集型数据库读取操作.所以基本上,一个请求来生成,比方说,生成10个不同的文档.要生成文档,只需要db读取来收集/处理数据.因此,我们基本上产生10个线程来处理10个文档,最后收集10个工作者返回的10个文档并合并它们并向客户端写回一个大响应.我们确定的是,当10个线程正在收集/处理数据时,会产生大量类似的数据库调用.所以我们想出的是围绕最常执行的db方法创建一个Aspect来缓存响应.方面配置为单例,方面使用的缓存自动连接到方面,并将范围设置为请求范围,以便每个请求都有自己的缓存.
问题:现在这个方法的问题是,当线程正在进行数据库调用而Aspect是interjects时,我们会遇到java.lang.IllegalStateException: No thread-bound request found异常.我理解的是完全有效的,因为线程正在请求上下文之外执行.
有没有办法绕过这个问题?是否可以将带有请求范围缓存的方面应用于这些线程调用的方法?
我认为你不能直接这样做.即使你可以,也会有点难看.但是,您可以生成唯一的请求标识符(甚至 - 使用会话ID,但要小心多个选项卡),并将其传递给每个处理线程.然后,方面可以使用该id作为缓存的密钥.缓存本身也将是单例,但是会有Map<String, X>,StringID和X 在哪里是缓存结果.
为了使事情更容易处理,您可以使用@Async方法(而不是手动生成线程),并且每个@Async方法都可以将缓存ID作为其第一个参数传递.
(当然,您的异步方法应该返回,Future<Result>以便您可以在请求线程中收集它们的结果)
| 归档时间: |
|
| 查看次数: |
11132 次 |
| 最近记录: |