首先我们要明白strtus中的action请求其实就servlet,那么servlet有什么特性?是不是线程安全的呢?
servlet的生命周期?
服务器只创建每个servlet的单一实例,首次创建servlet时,它的init方法会被调用,因此,init是放置一次性设置代码的地方,之后,针对每个用户的请求都会创建一个线程,该线程调用前面创建的实例方法。多个并发请求一般会导致多个线程同时调用service(线程安全),service方法会依据接受到HTTP请求的类型,调用doXXX方法。最后如果服务器卸载某个servlet就会调用servlet的destroy方法。
由于servlet是单例的,因此当多个线程请求时就会造成数据风险,但也并不是不可避免的风险,解决方法:
1.注意全局变量的使用、注意共有数据的访问
2.单线程访问servlet,继承singleThreadModel,这样就避免的全局变量数据的使用问题,但是该方法不提倡使用,数据并发访问会造成阻塞等待
Public class Servlet1 extends HttpServlet implements SingleThreadModel{
……..
}
3.添加方法同步锁Synchronized,但是该方法也不提倡,原因与2相同
Struts1的特性:
Struts2的特性:
在Spring的Bean配置中,存在这样两种情况:
- <bean id="testManager" class="com.sw.TestManagerImpl" scope="singleton" />
- <bean id="testManager" class="com.sw.TestManagerImpl" scope="prototype" />
当然,scope的值不止这两种,还包括了request,session 等。但用的最多的还是singleton单态,prototype多态。
singleton表示该bean全局只有一个实例,Spring中bean的scope默认也是singleton.
prototype表示该bean在每次被注入的时候,都要重新创建一个实例,这种情况适用于有状态的Bean.
转载scope默认信息:http://blog.sina.com.cn/s/blog_5f12739d0100cre0.html
webwork的Action不是线程安全的,要求在多线程环境下必须是一个线程对应一个独立的实例,不能使用singleton。所以,我们在Spring配置WebworkAction Bean时,需要加上属性scope=”prototype”或singleton=”false”。
singleton模式指的是对某个对象的完全共享,包括代码空间和数据空间,说白了,如果一个类是singleton的,假如这个类有成员变量,那么这个成员变量的值是各个线程共享的(有点类似于static的样子了),当线程A往给变量赋了一个值以后,线程B就能读出这个值。因此,对于前台Action,肯定不能使用singleton的模式,必须是一个线程请求对应一个独立的实例。推而广之,只要是带数据成员变量的类,为了防止多个线程混用数据,就不能使用singleton。对于我们用到的Service、Dao,之所以用了singleton,就是因为他们没有用到数据成员变量,如果谁的Service需要数据成员变量,请设置singleton=false。