struts2線程安全

問題:
Struts 2 Action對象爲每一個請求產生一個實例,因此沒有線程安全問題。
Spring的Ioc容器管理的bean默認是單實例的,上一次請求處理的狀態信息被保持下來,並影響了下一次的請求,實際上就是Action中的類變量被不同的請求讀取,出現錯誤結果

解決:就是不用單例, spring中bean的作用域設爲prototype,每個請求對應一個實例.

1、Struts1
Struts1是單例模式,也就是所,Web容器(例如:Tomcat)啓動的時候,就會實例化一個Action對象,那麼所有請求都是用的這個對象。所以當遇到2個請求併發的時候,那麼其實他們調用的是同一個類,這個時候當你在Action內部定義屬性的時候,就會產生線程同步的問題。
例如:
你在Action定義了一個 int i = 0;
然後在這個Action裏面的某一個方法裏面對這個i進行操作。當併發的時候就會遇到問題。
所以:我們在用struts1的時候不能在action裏面定義屬性。要用到只的話只能在方法裏面定義。
2、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類中只使用局部變量,不使用實例變量。
發佈了374 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章