Posted on 2007-01-25 20:29
兵臨城下 閱讀(1390)
評論(0) 編輯 收藏 所屬分類:
Java EE
???????????(以下所述只在WEB程序中)
??????????近期在項目調試時遇到一個關于Servlet的實例變量的問題,由于Servlet是多線程的,所以Servlet的實例變量是非線程安全的,在項目調試中出現多線程的同步問題。
?????????由于Web容器維護的Servlet在容器中只會創建一個實例,也就單例模式。Servlet多線程運行,則實例變量是多線程共享的,存在隱患,但很難發現!
?????????下面來說一下這個問題,比較離奇:
?????????原先的jsp頁面中,存在一個Hidden的Iframe來實現頁面上菜單聯動的功能,一直運行良好。最近把iframe去掉了,改用ajax來實現。在下拉菜單onchange時,同時發出三個請求,調用同一個servlet,在這個Servlet中存在一個實例變量來返回數據,由于線程變量是非線程安全的,所以出現了bug,這個bug很隱秘,不是每次都能測試出來。
?????????在這里我不想討論iframe和ajax的好壞,只是想討論一下實例變量和靜態變量。
?????????靜態變量大家肯定比較熟悉,使用靜態變量就是為了維護一個狀態,使得可以讓多實例共享這個變量,我們可以用它來實現一些類似緩存的功能。現在如果這個類的實現是一個單例的模式,那么靜態變量就失去了優勢。單例,那就意味著只能多線程使用,那么多線程中實例變量就是多線程共享的(非線程安全),此時實例變量的作用類似于靜態變量了。
?????????是不是可以這樣說,單例模式中可以用實例變量來實現靜態變量的功能呢???現在Spring中默認的都是單例模式(singleton)。
?????????但是個人觀點,不提倡使用實例變量,畢竟非線程安全。如果一定要使用的話,個人觀點只用實例變量來維護一些web資源(緩存功能,如xml資源等等,公司項目中有很多這樣的情況),不能在這個類中頻繁使用它,不安全(我遇到的就是這樣一個問題)。
?????????純屬個人觀點,歡迎大家發表意見,討論一下!