Spring的作用域
- singleton(單例):默認的scope,每個scope屬性來表示該bean的作用域,是bean的聲明周期膊爪。作用域為單例表示bean在第一次被注入時會創(chuàng)建一個單例對象绑蔫,改對象會一直被復用到應用結束
- prototype(多例):bean被定義為在每次注入時都會創(chuàng)建一個新的對象
- request:bean被定義為在每個http請求中創(chuàng)建一個單例對象,也就是說在單個請求中都會復用這一個單例對象
- session:bean被定義為在一個session的生命周期內(nèi)創(chuàng)建一個單例對象
- application:bean被定義為在servletContext的生命周期中復用一個單例對象
- websocket:bean被定義為在websocket的生命周期中復用一個單例對象
無狀態(tài)對象
- 由Spring管理得大多數(shù)對象其實都是一些無狀態(tài)的對象肿仑,這些對象不會因為多線程而導致狀態(tài)破壞很適合Spring的默認scope.每個單例的無狀態(tài)對象都是好線程安全的,換言之,只要是無狀態(tài)的對象,不管是單例還是多例欲间,都是線程安全的,只不過單例節(jié)省了不斷常見對象和GC的開銷断部。
- 無狀態(tài)的對象包括常用的DO猎贴,DTO,VO等只是作為數(shù)據(jù)的實體模型的對象蝴光,還有Service,DAO,Controller這些沒有自己的狀態(tài)她渴,只是用來執(zhí)行某些操作。
Bean的安全使用
Spring對于bean的多線程安全問題沒有任何保證與措施蔑祟,對于每個bean的線程安全問題趁耗,根本原因在于對每個bean自身的設計,不要在bean中聲明任何有狀態(tài)的實例變量或類變量疆虚,如果必須設置苛败,那么可以使用ThreadLocal把變量變?yōu)榫€程私有满葛,如果bean的實例變量或類變量需要在多個線程之間共享,那么需要使用syncronized,lock,CAS等實現(xiàn)線程同步
ThreadLocal的使用
- ThreadLocal思想就是為線程提供一個線程私有的變量副本著拭,這個多個線程可以所以修改自己線程局部的變量纱扭,不會影響其他線程。ThreadLocal含有一個ThreadLocalMap的內(nèi)部類儡遮,該類采取線性探測法實現(xiàn)HashMap,它的key值r為ThreadLocal對象并采用軟引用的方式來存儲變量副本
- ThreadLocal提供的是淺拷貝乳蛾,如果需要解決內(nèi)部狀態(tài)被改變的問題,可以通過重寫其內(nèi)部的initialValue()方法來實現(xiàn)深拷貝
- ThreadLocal與鎖機制不一樣的地方在于鄙币,鎖更強調(diào)的是如何同步多個線程去正確共享一個變量肃叶,ThreadLocal則是為了解決同一個變量如何不被多個線程共享。從性能開銷的角度來看十嘿,如果鎖機制是時間換空間因惭,那threadlocal就是空間換時間
- 為了安全使用ThreadLocal,必須像每次使用完鎖就解鎖一樣绩衷,在每次使用ThreadLocal后都要調(diào)用remove()來清理無效的Entry