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 

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

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



processActionCreate這個方法里去一窺究竟吧: 
1、先獲取類名 
2、根據類名去一個名為actions的map里查尋實例是否已經存在 
3、如果存在,則直接返回 
4、如果不存在,則創建一個新實例 
5、把創建好的action放到map里備用 

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




struts2 在struts1的基礎上做了改進 ,對於struts2 ,每次請求過來都會new一個新的action , 所以說struts2的action是線程安全的 , 但同時也帶來一個問題,每次都new一個action ,這樣action的實例太多 , 在性能方面還是存在一定的缺陷的。 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM