use*_*232 8 java spring multithreading
我已经声明了一个Spring bean,它会每隔几秒钟轮询我的电子邮件服务器.如果有邮件,它会抓取它,并尝试提取其中的任何附加文件.然后将这些文件提交给上传者,安全地存储它们.上传器也被声明为Spring bean.第三个bean将电子邮件的发件人与文件的文件名相关联,并将其存储在数据库中.
事实证明,当一些人试图同时发送电子邮件时,发生了一堆乱七八糟的事情.DB中的记录有错误的文件名.有些人根本没有获得文件名等.
我将问题归结为bean默认情况下将范围限定为单例.这意味着一堆线程可能同时搞乱了同一个实例.问题是如何解决这个问题.
如果我同步所有敏感方法,那么所有线程将堆叠起来并等待彼此,这有点违背了多线程的整个想法.
另一方面,将bean定义为"请求"将创建每个bean的新实例,如果我们谈论内存消耗和线程调度,这也不是很好
我很迷惑.我该怎么办?
我同意@Bozho和@stivio的答案.
首选选项是在单例作用域bean中传递不存储状态,并将上下文对象传递给方法,或者使用为每个处理周期创建的原型/请求作用域bean.通过选择其中一种方法,通常可以避免同步,并且可以获得更高的性能,同时避免死锁.只要确保你没有修改任何共享状态,比如静态成员.
每种方法都有利弊:
在大多数简单的情况下,我倾向于使用服务方法.您还可以让这些单例bean创建一个处理对象,该对象可以保存计算的状态.这是一个可以为更复杂的场景提供最佳服务的解决方案.
编辑: 有些情况下,你有一个单独的bean取决于原型范围的bean,并且你想为每个方法调用一个新的原型bean实例.Spring提供了几种解决方案:
第一种是使用方法注入,如Spring参考文档中所述.我不太喜欢这种方法,因为它迫使你的班级变得抽象.
第二种方法是使用ServiceLocatorFactoryBean或您自己的工厂类(需要注入依赖项,并调用构造函数).在大多数情况下,这种方法非常有效,并且不会将您联系到Spring.
在某些情况下,您还希望原型bean具有运行时依赖性.我的一位好朋友在这里写了一篇很好的帖子:http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/.
归档时间: |
|
查看次数: |
4384 次 |
最近记录: |