關於struts2 的單例和多例及執行緒安全的問題
阿新 • • 發佈:2019-01-24
我知道struts 2的Action是多例項的並非單例,也就是每次請求產生一個Action的物件。原因是:struts 2的Action中包含資料,例如你在頁面填寫的資料就會包含在Action的成員變數裡面。如果Action是單例項的話,這些資料在多執行緒的環境下就會相互影響,例如造成別人填寫的資料被你看到了。它存在著執行緒不安全。
而struts 1的Action是單例項的,因為它的資料儲存在Form類中,多執行緒環境下,Action只負責處理一些邏輯,並沒有資料,也就是大家把它當做一個工具使用。同樣servlet也是單例項的。它是執行緒安全的
而在使用spring來生成action的時候,發現生成的action居然全是單例的。這不是讓我的程式預設就跑出bug來麼?上個使用者提交的資訊,如果下個使用者沒填,居然跑到上個用 戶輸入的資訊去了。 背景: 1) Struts2會對每一個請求,產生一個Action的例項來處理. 2) Spring的Ioc容器管理的bean預設是單例項的. 首先從資料安全性的問題上考慮,我們的Action應該保證是多例的,這樣才不會出現數據問題。但是如果有的action比如只有admin才能操作,或者某些action,全站公用一個 來提高效能,這樣的話,就可以使用單例模式 不過幸好,Spring的bean可以針對每一個設定它的scope,所以,上面的問題就不是問題了。 如果用單例,就在spring的action bean配置的時候設定scope="prototype"或者singleton = "false" 單例模式是spring推薦的配置,它在高併發下能極大的節省資源,提高服務抗壓能力。spring IOC的bean管理器是“絕對的執行緒安全”。 用ThreadLocal是為了保證執行緒安全,實際上ThreadLoacal的key就是當前執行緒的Thread例項。 單例模式下,spring把每個執行緒可能存線上程安全問題的引數值放進了ThreadLocal。這樣雖然是一個例項在操作,但是不同執行緒下的資料互相之間都是隔離的, 因為執行時建立和銷燬的bean大大減少了,所以大多數場景下這種方式對記憶體資源的消耗較少,而且併發越高優勢越明顯。 總的來說就是,單利模式因為大大節省了例項的建立和銷燬,有利於提高效能,而ThreadLocal用來保證執行緒安全性。