struts2的action是线程安全的,struts1的action不是线程安全的

为什么struts2的action是线程安全的,struts1的action不是线程安全的?

先对struts1和struts2的原理做一个简单的讲解

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

另外说几句,当struts交由spring管理的时候,spring的bean配置默认是单例的,

如果action是有状态的,必须显示的配置为prototype

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

下面是struts1.2的源码:

当请求过来时,去找指定的action,如果有就直接取出来,如果没有就new一个新的action放到map中。

/**  
 * The set of Action instances that have been created and  
 * initialized, keyed by the fully qualified Java class name of the  
 * Action class.  
 */  
protected HashMap actions = new HashMap();

processActionCreate这个方法里去一窥究竟吧:

1、先获取类名

2、根据类名去一个名为actions的map里查寻实例是否已经存在

3、如果存在,则直接返回

4、如果不存在,则创建一个新实例

5、把创建好的action放到map里备用

protected Action processActionCreate(HttpServletRequest request,   
                                         HttpServletResponse response,   
                                         ActionMapping mapping)   
        throws IOException {   
  
        // Acquire the Action instance we will be using (if there is one)   
        String className = mapping.getType();//1、先获取类名    
        ...   
        Action instance = null;   
        synchronized (actions) {   
  
            // Return any existing Action instance of this class   
            instance = (Action) actions.get(className);//2、根据类名去map里查寻实例是否已经存在   
            if (instance != null) {   
                return (instance); //3、如果存在,则直接返回   
            }   
  
            // Create and return a new Action instance   
            //4、如果不存在,则创建一个新实例   
            instance = (Action) RequestUtils.applicationInstance(className)   
  
            instance.setServlet(this.servlet);   
            actions.put(className, instance);//5、把创建好的action放到map里   
        }   
        ...   
        return (instance);   
  
    }

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

struts1是单例模式,而struts2是原型模式

相关推荐