spring的线程安全问题各位高手,是这样的。我用spring的方法封装我的类,比如bean idmanageService class
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的方法不行哈
------解决方案--------------------
每次调用就是一次压栈,方法中的变量被压入栈中,也就是说不通线程调用同一个方法的时候里面的变量是对应的不同的堆栈哈
可能解释的不是很准确
[解决办法] 探讨 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> …[解决办法] 探讨 我还想问一下,就是说,spring+struts+hibernate的时候,只有action的singleton为false,其他的bean都声明为singleton,那么要是多个action并发的时候,每个action都会去调用这些bean(此时被调用的bean都是返回同一个bean的呀),那么这个时候,为什么是线程安全的呢? 谢谢你了[解决办法] 看完这贴,忽然发现我已经完全不懂spring了,
不过我有个疑问,以前我使用spring时总是注入某些服务的接口实例,这些实例仅仅提供符合接口的一些逻辑或操作数据库的方法,压根没有什么临界资源,不需要什么额外的保护,奇了怪了。
对了,再问个菜鸟问题,spring送上门的那个实例,默认是同一个对象(单例)??
[解决办法] 如果是singleton,那么本身就是安全的,主要要保证你另10个线程是的安全性
[解决办法] 其实确实不一定能保证安全,刚才把singleton想成自己写的了,刚才说错了,如果要同步还是得加同步块
[解决办法] 1. 多线程对同一对象的访问,只有会修改BEAN(Service)的时候,才需要同步该对象;
而同时Read的问题,是不需要同步该对象的
2. Struts 1中的Action为单例singleton, 多个Request是共享同一个Action的;
若有需要对Action中的共享对象(如service)修改,是要同步的(一般调用Service的DAO方法,只是Read,非Write,并非需要同步,原理同1)
Struts 2中的Action非单例singleton,针对用户的每一个Request,会NEW出对应ACTION实例,更不需同步
3. Spring的BEAN组建,默认方式为:singleton, 若会多线程修改Bean,则改用"Prototype"
[解决办法] 一般DAO只负责数据库的行为操作,DAO的实现类中没有成员变量,这种情况下,DAO没有线程安全问题。
楼主的这个方法,貌似只解决了单例问题,看不出来是否存在线程安全问题。
ThreadLocal应该是线程访问数据对象的一种应用方式,貌似并不能解决线程安全问题。
楼主可以看一下,alarmDao、mainMenuDao、managerDao和manageService中是否含有其他的成员变量,
如果没有,就不用考虑线程安全的问题;
如果有,最笨的方法就是把那些访问过成员变量的方法都添加上synchronized关键字。