为什么struts2的action是线程安全的,struts1的action不是线程安全的? 
先对struts1和struts2的原理做一个简单的讲解 

对于struts1 ,当第一次**.do的请求过来时,在内存中的actionmapping中找到相对应的action,然后new出这个action放在缓存中,当第二 次一样的请求过来时,还是找的这个action,所以对于struts1来说,action是单实例的 ,只有一个,如果在action中定义变量,就要非常小心了,因为并发问题,可能带来灾难性的后果,也不是不可以,我们可以加锁达到同步,只是在性能上就 要折衷了。 

另外说几句 ,当struts交由spring管理的时候 ,spring的bean配置默认是单例的 , 
如果action是有状态的 ,必须显示的配置为prototype 

1 <bean id= "saveUserAction"   class = "com.test.action.user.SaveUserAction"  scope= "prototype" >  
2     <property name="service"  ref= "userService" ></property>  
3 </bean>  

 

下面是struts1.2的源码: 
当请求过来时,去找指定的action,如果有就直接取出来,如果没有就new一个新的action放到map中。

1 Java代码  收藏代码  
2   
3     /**    
4      * The set of Action instances that have been created and    
5      * initialized, keyed by the fully qualified Java class name of the    
6      * Action class.    
7      */      
8     protected HashMap actions = new HashMap();      

processActionCreate这个方法里去一窥究竟吧: 
1、先获取类名 
2、根据类名去一个名为actions的map里查寻实例是否已经存在 
3、如果存在,则直接返回 
4、如果不存在,则创建一个新实例 
5、把创建好的action放到map里备用

 1 Java代码  收藏代码  
 2   
 3     protected Action processActionCreate(HttpServletRequest request,       
 4                                              HttpServletResponse response,       
 5                                              ActionMapping mapping)       
 6             throws IOException {       
 7           
 8             // Acquire the Action instance we will be using (if there is one)       
 9             String className = mapping.getType();//1、先获取类名        
10             ...       
11             Action instance = null;       
12             synchronized (actions) {       
13           
14                 // Return any existing Action instance of this class       
15                 instance = (Action) actions.get(className);//2、根据类名去map里查寻实例是否已经存在       
16                 if (instance != null) {       
17                     return (instance); //3、如果存在,则直接返回       
18                 }       
19           
20                 // Create and return a new Action instance       
21                 //4、如果不存在,则创建一个新实例       
22                 instance = (Action) RequestUtils.applicationInstance(className)       
23           
24                 instance.setServlet(this.servlet);       
25                 actions.put(className, instance);//5、把创建好的action放到map里       
26             }       
27             ...       
28             return (instance);       
29           
30         }     

struts2 在struts1的基础上做了改进 ,对于struts2 ,每次请求过来都会new一个新的action , 所以说struts2的action是线程安全的 , 但同时也带来一个问题,每次都new一个action ,这样action的实例太多 , 在性能方面还是存在一定的缺陷的。