struts2 的線程安全

問題: Struts 2 Action對象爲每個請求產生一個實例,所以沒有線程安全問題。 Spring的Ioc容器管理的bean默認是單實例的,上一次請求處理的狀態信息被保持下來,並影響了下一次的請求,實際上就是Action中的類變量被不一樣的請求讀取,出現錯誤結果 解決:就是不用單例, spring中bean的做用域設爲prototype,每一個請求對應一個實例. 一、Struts1 Struts1是單例模式,也就是所,Web容器(例如:Tomcat)啓動的時候,就會實例化一個Action對象,那麼全部請求都是用的這個對象。因此當遇到2個請求併發的時候,那麼其實他們調用的是同一個類,這個時候當你在Action內部定義屬性的時候,就會產生線程同步的問題。 例如: 你在Action定義了一個 int i = 0; 而後在這個Action裏面的某一個方法裏面對這個i進行操做。當併發的時候就會遇到問題。 因此:咱們在用struts1的時候不能在action裏面定義屬性。要用到只的話只能在方法裏面定義。 二、struts2 Struts 2 Action對象爲每個請求產生一個實例,所以沒有線程安全問題。因此咱們能夠在Struts2的Action裏面去定義屬性。可是Struts2因爲 Action和普通的Java類沒有任何區別(也就是不用像Struts1裏面那樣去實現一個Struts的接口,有興趣的朋友能夠本身去了解),因此咱們能夠用Spring去管理Struts2的Action,這個時候咱們就要注意了,由於當咱們在spring裏面去定義bean的時候,spring默認用的是單例模式。因此在這個時候,你就要修改Spring的配置文件---即修改scope爲prototype。 爲何struts1中並無考慮到線程問題,由於全部的代碼都是寫在execute的方法中,全部變量都是定義在裏面,因此沒有線程安全問題。 而如今的struts2就不同了。struts2的action中就像一個POJO同樣,定義了不少的類變量。這就有線程安全問題了。。此時,就使用scope=prototype來指定是個原型模式,而不是單例,這樣就解決了線程安全問題。每一個線程都是一個新的實例。。 可是,線程同步是不得以的方法,是比較複雜的,並且會帶來性能的損失。等效的代碼中,不須要同步在編寫容易度和性能上會更好些。 我這裏強調的是什麼代碼是始終爲線程安全的、是不須要同步的。以下: 1)常量始終是線程安全的,由於只存在讀操做。 2)對構造器的訪問(new 操做)是線程安全的,由於每次都新建一個實例,不會訪問共享的資源。 3)最重要的是:局部變量是線程安全的。由於每執行一個方法,都會在獨立的空間建立局部變量,它不是共享的資源。局部變量包括方法的參數變量。 struts user guide裏有: Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class. 譯:只使用用局部變量。--編寫線程安全的代碼最重要的原則就是,在Action類中只使用局部變量,不使用實例變量。
相關文章
相關標籤/搜索