struts2整合spring线程安全问题

                                                Struts2 整合spring 线程安全问题


     最近在看关于线程安全的书,对自己做过的项目进行了一番新的审视,尤其是ssh项目

     首先线程安全问题是如何产生的,关于这一点,我看过许多网上的资料,甚至是书上都是如此表述:比如有一个类Person 有个属性是name,线程1修改了这个属性的name,要进行存入数据库操作的时候,线程2又修改了这个name,这样线程1就存入了一个线程2修改过的数据了。
关于此类假设,我不知道是不是人云亦云,我不能说你错了,但一定是不严谨的,在这个例子中,只有当Person类在线程1和线程2 共用一个实例的时候,才会出现上述情况。如果类Person有两个实例person1 和person2 ,线程1修改的是person1中的name,线程2修改的是person2中的name,那么根本不会出现这种事。


     就因为这句不贴切的表述,让我迷糊了很久,我一直不明白,类的不同实例分配的是不同的内存区域,线程说的再如何神乎也不可能影响到不同的实例之间的数据安全,为什么你们一定要拿类说线程安全,而不是拿实例说?


由此我也想到了struts2,以前也做过struts1和Servlet的项目,他们的多个请求(可以看作多个线程)之间共用的是一个action 或 Servlet,因此如果类中有定义变量,则有可能引发线程安全问题。这里对struts1和Servlet不做详细讨论,下面说说Struts2 整合spring:
Struts2 整合spring的方式比较常用的两种(也许还有其他的方法):参考 struts2+spring的两种整合方式


       Struts2他是多实例的,对于每个请求都会生成1个实例,spring默认是单实例的,所以对于无Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式,需要在spring的action Bean中加业务逻辑控制器类配置为scope=”prototype”。对于有Spring插件(Struts2-spring-plugin-XXX.jar)的整合方式:反编译StrutsSpringObjectFactory以及相关的代码才发现,如果在struts action的配置文件中<action name=".." class=".."/>中class写的如果是完整的包名和类名的话就是struts创建action对象,也就是多实例的;如果是spring配置文件中的 bean的名字的话就是spring创建,那么单实例还是多实例就由spring的action Bean中的业务逻辑控制器类是否配置为scope=”prototype”,有就是多实例的,没有就是单实例的,顺序是先从spring中找,找不到再从struts配置文件中找。


       综上所述,即如果action 是单实例 即线程不安全,action是多实例就是线程安全。那么真的是这样吗?其实也不尽然,如果在action是多实例的工程环境中存在 定时任务(一般会重启一个新的线程)等重启线程的业务操作的话,那么这个线程安全仍然需要打上一个问号。这个时候需要看这多个线程之间是否有共享变量,这些共享变量就应当同步处理。

转载请注明出处:
http://chenqiuzhen.iteye.com/blog/1917518

相关推荐