tomcat容器对servlet的实现采用的是单例模式,对于一个servlet类,永远只有一个servlet对象存在。java
下面咱们来解释为何Struts1是线程不安全的。web
一、Struts1spring
Struts1是对Java web servlet接口的直接实现,因此它继承了tomcat对servlet的实现,每个struts1里面的action都对应的是一个servlet class,因此这里的action在被tomcat实例化以后也是单例的,因此,struts1就产生了多线程问题。tomcat
因此:咱们在用struts1的时候不能在action里面定义属性。要用到只的话只能在方法里面定义。安全
那至于为何把属性的定义放到方法里面就不会有多线程的问题了,这个问题但愿各位读者去查看有关JMM(java memory model)里面有关java内存模式如何给方法分配内存的内容, 我相信大家会找到答案。多线程
二、struts2prototype
上面咱们了解了Struts1里面的多线程问题,那Struts2是怎么解决这个问题的呢?其实道理很是简单,缘由就是Strtus2会获取到用户的http请求,而后负责给每一个请求实例化一个Action 对象,可是你们注意,这里的action对象和Struts1里面的action对象彻底不是一个概念,struts1里面的action类就是一个servlet类,而这里的action类只是一个普通的java class。这也就是为何Struts1里面的action是线程不安全的,而struts2里面的action是线程安全的缘由。线程
那咱们在回头来看看struts2对servlet的处理和struts1有什么不一样。看过前面分析的读者确定知道,struts1的 action对servlet没有进行任何的包装,它是直接实现的Java WEB API 里面的servlet 接口。因此才会有线程安全的问题,可是struts2底层帮咱们封装了Servlet,使开发人员不用直接接触Servlet。具体作法是:对象
Strtus2截获servlet请求,而后给每一个请求实例化一个Action对象,请求结束以后销毁Action对象。至于Strtus2具体是怎么作的,我这里不赘叙,你们能够去参看Struts2的有关介绍。继承
在Struts2中因为 Action和普通的Java类没有任何区别(也就是不用像Struts1里面那样去实现一个Struts的接口,有兴趣的朋友能够本身去了解),因此咱们能够用Spring去管理Struts2的Action,这个时候咱们就要注意了,由于当咱们在spring里面去定义bean的时候,spring默认用的是单例模式。因此在这个时候,你就要修改Spring的配置文件---即修改scope为prototype。