springMVC一個Controller處理所有用戶請求的並發問題


有狀態和無狀態的對象基本概念:
有狀態對象(Stateful Bean),就是有實例變量的對象 ,可以保存數據,是非線程安全的。一般是prototype scope。
無狀態對象(Stateless Bean),就是沒有實例變量的對象,不能保存數據,是不變類,是線程安全的。一般是singleton scope。

如Struts2中的Action,假如內部有實例變量User,當調用新增用戶方法時,user是用來保存數據,那么此action是有狀態對象。多個線程同時訪問此action時 會造成user變量的不一致。所以action的scope要設計成prototype,或者,User類放到threadLocal里來保持多個線程不會造成User變量的亂串(此種場景沒必要放到threadLocal內)。

而Service內部一般只有dao實例變量 如userDao, 因為userDao是無狀態的對象(內部無實例變量且不能保存數據),所以service也是無狀態的對象。

public   class  XxxAction{

   // 由於多線程環境下,user是引用對象,是非線程安全的  

  public  User user;

  ......

}

public   class  XxxService {  

  // 雖然有billDao屬性,但billDao是沒有狀態信息的,是Stateless Bean.   

  BillDao billDao;  

  ......

}

對於那些會以多線程運行的單例類

局部變量不會受多線程影響,
成員變量會受到多線程影響。

多個線程調用同一個對象的同一個方法: 
如果方法里無局部變量,那么不受任何影響
如果方法里有局部變量,只有讀操作,不受影響;存在寫操作,考慮多線程影響值;

例如Web應用中的Servlet,每個方法中對局部變量的操作都是在線程自己獨立的內存區域內完成的,所以是線程安全的。 
對於成員變量的操作,可以使用ThreadLocal來保證線程安全。 

springMVC中,一般Controller、service、DAO層的scope均是singleton;

每個請求都是單獨的線程,即使同時訪問同一個Controller對象,因為並沒有修改Controller對象,相當於針對Controller對象而言,只是讀操作,沒有寫操作,不需要做同步處理。

 

Service層、Dao層用默認singleton就行,雖然Service類也有dao這樣的屬性,但dao這些類都是沒有狀態信息的,也就是 相當於不變(immutable)類,所以不影響。

Struts2中的Action因為會有User、BizEntity這樣的實例對象,是有狀態信息 的,在多線程環境下是不安全的,所以Struts2默認的實現是Prototype模式。在Spring中,Struts2的Action中scope 要配成prototype作用域。

 

 


免責聲明!

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



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