關於例項變數和靜態變數的一點疑問

xuechen0721發表於2007-02-03
(以下所述只在WEB程式中)
近期在專案除錯時遇到一個關於Servlet的例項變數的問題,由於Servlet是多執行緒的,所以Servlet的例項變數是非執行緒安全的,在專案除錯中出現多執行緒的同步問題。
由於Web容器維護的Servlet在容器中只會建立一個例項,也就單例模式。Servlet多執行緒執行,則例項變數是多執行緒共享的,存在隱患,但很難發現!
下面來說一下這個問題,比較離奇:
原先的jsp頁面中,存在一個Hidden的Iframe來實現頁面上選單聯動的功能,一直執行良好。最近把iframe去掉了,改用ajax來實現。在下拉選單onchange時,同時發出三個請求,呼叫同一個servlet,在這個Servlet中存在一個例項變數來返回資料,由於執行緒變數是非執行緒安全的,所以出現了bug,這個bug很隱秘,不是每次都能測試出來。
在這裡我不想討論iframe和ajax的好壞,只是想討論一下例項變數和靜態變數。
靜態變數大家肯定比較熟悉,使用靜態變數就是為了維護一個狀態,使得可以讓多例項共享這個變數,我們可以用它來實現一些類似快取的功能。現在如果這個類的實現是一個單例的模式,那麼靜態變數就失去了優勢。單例,那就意味著只能多執行緒使用,那麼多執行緒中例項變數就是多執行緒共享的(非執行緒安全),此時例項變數的作用類似於靜態變數了。
是不是可以這樣說,單例模式中可以用例項變數來實現靜態變數的功能呢?? 現在Spring中預設的都是單例模式(singleton)。
但是個人觀點,不提倡使用例項變數,畢竟非執行緒安全。如果一定要使用的話,個人觀點只用例項變數來維護一些web資源(快取功能,如xml資源等等,公司專案中有很多這樣的情況),不能在這個類中頻繁使用它,不安全(我遇到的就是這樣一個問題)。
純屬個人觀點,歡迎大家發表意見,討論一下!

相關文章