springMVC一個Controller處理全部用戶請求的併發問題

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

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

而Service內部通常只有dao實例變量 如userDao, 由於userDao是無狀態的對象(內部無實例變量且不能保存數據),因此service也是無狀態的對象。多線程

public   class  XxxAction{less

   // 因爲多線程環境下,user是引用對象,是非線程安全的  prototype

  public  User user;線程

  ......設計

}對象

public   class  XxxService {  blog

  // 雖然有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做用域。

 

 

標籤: 有狀態無狀態單例

相關文章
相關標籤/搜索