1. 程式人生 > >struts2的action是執行緒安全的,struts1的action不是執行緒安全的真正原因

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中。
Java程式碼 收藏程式碼

/**

  • 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是原型模式