日期:2014-05-20  浏览次数:20684 次

spring的线程安全问题
各位高手,是这样的。我用spring的方法封装我的类,比如
<bean id="manageService" class="org.service.manageServiceImpl">
  <property name="alarmDao">
  <ref bean="alarmDao"/>
  </property>
  <property name="mainMenuDao">
  <ref bean="mainMenuDao"/>
  </property>
  <property name="managerDao">
  <ref bean="managerDao"/>
  </property>
  </bean>

然后呢,我需要在多线程中调用这个bean,比如我new了10个线程,在每个线程中都要用到这个bean,而这个bean又是singleton的,而多线程对同一对象进行操作会有线程不安全的问题,那么请问,我这样做是否是线程安全的呀?我知道spring用ThreadLocal来管理事务管理、任务调度、AOP等模块,但是这里这个bean是我自己定义的,spring会自动给我这个bean用上ThreadLocal,使其线程安全吗?

------解决方案--------------------

 Spring 默认是单例模式,为了解决这个问题, 只需要修改Bean的xml文件,scope="prototype" 修改如下:

<bean id="manageService" class="org.service.manageServiceImpl" scope="prototype"> 
<property name="alarmDao"> 
<ref bean="alarmDao"/> 
</property> 
<property name="mainMenuDao"> 
<ref bean="mainMenuDao"/> 
</property> 
<property name="managerDao"> 
<ref bean="managerDao"/> 
</property> 
</bean>
------解决方案--------------------
探讨

Spring 默认是单例模式,为了解决这个问题, 只需要修改Bean的xml文件,scope="prototype" 修改如下:

<bean id="manageService" class="org.service.manageServiceImpl" scope="prototype">
<property name="alarmDao">
<ref bean="alarmDao"/>
</property>
<property name="mainMenuDao">
<ref bean="mainMenuDao"/>
</property>
<property name="managerDao">
<ref bean="managerDao"/>
</property>
</bean>

------解决方案--------------------
Spring中bean的范围如下:

singleton
Scopes a single bean definition to a single object
instance per Spring IoC container.
prototype 
Scopes a single bean definition to any number of
object instances.
request
Scopes a single bean definition to the lifecycle of a
single HTTP request; that is each and every HTTP
request will have its own instance of a bean created
off the back of a single bean definition. Only valid in
the context of a web-aware Spring ApplicationContext.
session
Scopes a single bean definition to the lifecycle of a
HTTP Session. Only valid in the context of a
web-aware Spring ApplicationContext.
global session
Scopes a single bean definition to the lifecycle of a
global HTTP Session. Typically only valid when
used in a portlet context. Only valid in the context of
a web-aware Spring ApplicationContext.


------解决方案--------------------
spring并没有为你的类提供线程安全哈,上面一位老兄说的把把scope改为"prototype"
设置成原型可以解决这个问题
还有的话如果你的类没有类变量存在也不会存在线程安全问题
如果有类变量的话你把变量存放在ThreadLocal里面,根据ThreadLocal来存取类变量达到线程同步也没有问题
------解决方案--------------------
对 只有方法不存在线程安全问题
当然static的方法不行哈
------解决方案--------------------